繁体   English   中英

Win32 应用程序关闭后仍在后台运行

[英]Win32 application still running in background after closing

我是初学者程序员。

在此代码中,我想使用 C 语言在 Win32 API 中创建一种颜色的 window。 我正在使用 Windows PowerShell 和 MinGW 来编译它。 它可以工作,但是每当我在关闭它后尝试再次编译它时,我都会收到此错误: .../mingw32/bin/ld.exe: cannot open output file out.exe: Permission denied collect2.exe: error: ld returned 1 exit status

就我而言,这是一个链接问题,因为 Windows 无法与已经在执行的程序建立链接。 我不想一直在任务管理器中终止执行。

我不认为代码超出了微软文档告诉我的范围,我只是将它包装在函数和结构中,而不是在 WinMain 中编写所有内容,可以在那里找到应用程序循环。 我正在 WM_CREATE 中创建一个 RGB 数组并将其传递给 WM_PAINT 中的 HBITMAP,以防您想知道我做了什么,这就是为什么我稍后会假装要更改的重复高度和宽度。 这是代码:

#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;
}

我也尝试使用 exit() 而不是最后返回 0 但没有成功。 我很欣赏这些回应。

您的消息循环结构不正确。 仅当PeekMessage()返回 false 时才到达您的if语句,这意味着msg的内容是indeterminate 所以if永远不会看到有效的WM_QUIT消息(或任何有效的消息,就此而言)来打破循环。

摆脱running变量,并改用此循环:

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM