Reputation: 3
I am a beginner programmer.
In this code I want to create a window of one color in Win32 API using the C language. I am using the Windows PowerShell and MinGW to compile it. It works, but whenever I try to compile it again after closing it I get this error: …/mingw32/bin/ld.exe: cannot open output file out.exe: Permission denied collect2.exe: error: ld returned 1 exit status
As far as I am concerned, this is a linkage problem and it occurs because Windows cannot make the linkage with the program already being in execution. I do not wish to kill the execution all the time in the Task Manager.
I don't think the code is beyond what Microsoft's documentation tells me to do, I have simply wrapped it in functions and structs instead of writing everything in WinMain, the application loop can be found there. I am creating an RGB array in WM_CREATE and passing it to HBITMAP in WM_PAINT in case you are wondering what I have done, that's why the repeated height and width which I pretend to change later. Here is the code:
#include<windows.h>
#include<stdlib.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Window Procedure
HBITMAP bitmap_handle;
COLORREF *rgb_p=NULL;
LRESULT CALLBACK window_procedure_func(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
{
int width=500;
int height=500;
rgb_p=(COLORREF*)malloc(width*height*sizeof(COLORREF));
int pixel_count=0;
for(int row=0; row<height; row++)
{
for(int col=0; col<width; col++)
{
rgb_p[pixel_count]=RGB(255, 0, 0);
pixel_count++;
}
}
}
break;
case WM_PAINT:
{
int width=500;
int height=500;
HBITMAP bitmap_handle=CreateBitmap(width, height, 1, 32, rgb_p);
PAINTSTRUCT ps;
HDC hdc;
BITMAP bitmap;
HDC hdcMem;
HGDIOBJ oldBitmap;
hdc = BeginPaint(hWnd, &ps);
hdcMem = CreateCompatibleDC(hdc);
oldBitmap = SelectObject(hdcMem, bitmap_handle);
GetObject(bitmap_handle, sizeof(bitmap), &bitmap);
BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, oldBitmap);
DeleteDC(hdcMem);
EndPaint(hWnd, &ps);
}
break;
case WM_CLOSE:
{
DestroyWindow(hWnd);
}
break;
case WM_DESTROY:
{
free(rgb_p);
DeleteObject(bitmap_handle);
PostQuitMessage(0);
}
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Simple functions to initalize a window
struct window_wrapper
{
WNDCLASS window_class;
HWND window_handle;
};
WNDCLASS window_class_ini(char *window_name, HINSTANCE instance_handle, WNDPROC window_procedure)
{
WNDCLASS window_class={};
window_class.lpfnWndProc=window_procedure;
window_class.hInstance=instance_handle;
window_class.lpszClassName=window_name;
return window_class;
}
HWND window_handle_ini(char *window_name, HINSTANCE instance_handle, int width, int height)
{
return CreateWindow(
window_name,
window_name,
WS_OVERLAPPEDWINDOW,
250, 250, width, height,
NULL,
NULL,
instance_handle,
NULL);
}
struct window_wrapper *malloc_window_wrapper(char *window_name, HINSTANCE instance_handle, WNDPROC window_procedure, int windows_status, int width, int height)
{
struct window_wrapper *window_wrapper_p=NULL;
window_wrapper_p=(struct window_wrapper*)malloc(sizeof(struct window_wrapper));
window_wrapper_p->window_class=window_class_ini(window_name, instance_handle, window_procedure);
RegisterClass(&window_wrapper_p->window_class);
window_wrapper_p->window_handle=window_handle_ini(window_name, instance_handle, width, height);
ShowWindow(window_wrapper_p->window_handle, windows_status);
return window_wrapper_p;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Windows Entry Point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
LRESULT CALLBACK (*procedure_p)(HWND, UINT, WPARAM, LPARAM)=&window_procedure_func;
struct window_wrapper *wrapper=malloc_window_wrapper("window_name", hInstance, (WNDPROC)procedure_p, nCmdShow, 500, 500);
MSG msg={};
int running=1;
while(running)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message==WM_QUIT)
{
running=0;
}
}
free(wrapper);
return 0;
}
I have tried to use exit() also instead of return 0 at the end but no success. I appreciate the responses.
Upvotes: 0
Views: 1031
Reputation: 597971
Your message loop is structured incorrectly. Your if
statement is reached only when PeekMessage()
returns false, meaning the contents of msg
are indeterminate. So the if
will never see a valid WM_QUIT
message (or any valid message, for that matter) to break the loop.
Get rid of the running
variable, and use this loop instead:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDPROC procedure_p = &window_procedure_func;
struct window_wrapper *wrapper = malloc_window_wrapper("window_name", hInstance, procedure_p, nCmdShow, 500, 500);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
free(wrapper);
return 0;
}
Upvotes: 3