c++ - WinApi任务查杀

标签 c++ winapi task

我有 super 简单的 WinApi 程序。关闭按钮不会破坏程序的进程。应该添加什么?

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE hINSTANCE;

int WINAPI WinMain(HINSTANCE hInstance,
               HINSTANCE hPrevInstance,
               LPSTR lpstr,
               int nCmdShow) {

// VARIABLES
    TCHAR className[] = _T("win32api");
    TCHAR windowName[] = _T("Protected Window");

    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_INFORMATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = className;
    wcex.hIconSm = LoadIcon(NULL, IDI_SHIELD);

    if (!RegisterClassEx(&wcex)) {
        MessageBox(NULL, _T("Cannot register window"), _T("Error"), MB_OK | MB_ICONERROR);
        return 0;
    }

     HWND hWnd = CreateWindow(className,
                              windowName,
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              300,
                              300,
                              NULL,
                              NULL,
                              hInstance,
                              NULL);

    if (!hWnd) {
        MessageBox(hWnd, _T("Call to register windows isn't working"), _T("Error"), NULL);
        return 1;
    }

    hINSTANCE = hInstance;
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    MSG msg;

    while (GetMessage(&msg, hWnd, 0, 0) != 0 || GetMessage(&msg, hWnd, 0, 0) != -1) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.lParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uInt, WPARAM wParam, LPARAM lParam) {
    PAINTSTRUCT ps;
    HDC hdc;
    switch (uInt) {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        TextOut(hdc, 10, 20, _T("Text sample right here boyz."), _tcsclen(_T("Text sample right here boyz.")));
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, uInt, wParam, lParam);
        break;
    }

    return 0;
}

如果我再添加一个案例

case WM_CLOSE:
    PostQuitMessage(0);
    break;

它根本不关闭(按关闭按钮没有做任何事情)。非常感谢任何其他提示。

最佳答案

你的消息循环是错误的,原因有二:

  1. 您正在调用 GetMessage() 两次。不要那样做!想想如果你这样做会发生什么。如果 || 左侧的 GetMessage() 调用检测到 WM_QUIT(它不能,请参阅下文),它会返回 0。这会导致 || 调用右侧的 GetMessage(),忽略 WM_QUIT之前的调用并阻塞循环,直到新消息稍后到达。您应该在每个循环迭代中只调用一次 GetMessage(),然后根据需要对返回值进行操作:

    BOOL bRet;
    
    do
    { 
        bRet = GetMessage(&msg, hWnd, 0, 0);
        if (bRet == 0) break;
        if (bRet == -1)
        {
            // handle the error and possibly exit
        }
        else
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
    }
    while (1);
    
  2. 但是,您还按 HWND ( don't do that! ) 过滤消息,因此它只会返回通过以下方式发布到指定 HWND 的消息PostMessage()PostQuitMessage() 将其 WM_QUIT 消息发布到调用线程本身的输入队列,而不是 HWND。所以过滤永远不会看到 WM_QUIT 消息。为了让 WM_QUIT 打破循环,您需要完全停止按 HWND 进行过滤,或者至少定期进行未过滤的调用。

您的消息循环应该看起来像这样。这是标准消息循环:

while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

注意在这种情况下,there is no need to handle -1 from GetMessage()! .

关于c++ - WinApi任务查杀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36871265/

相关文章:

c++ - GCC: "__unused__"与变量属性中的 "unused"

c - 从 Windows 内核模式驱动程序确定文件所有者

c++ - Windows中如何取消 'system key down'状态

c++ - WINAPI 事件对象意外行为

c# - wcf 基于任务的异步模式

c# - 使用tasks和ContinueWith来实现调度器

c# - 任务的协变和逆变

C++重载+运算符友元函数

c++ - windows上qt应用的内存泄漏检测工具

c++ - 关于 boost::unique_future 的文档