如何优化winapi

时间:2018-11-18 12:28:32

标签: c++ winapi

我试图创建一个公共窗口,但是当创建该窗口时,我发现他正在消耗过多的CPU。 this is the image of task manager when window is running'这样。我应该如何优化代码以减少处理器负载,以使应用程序能够在后台模式下工作而又不增加处理器负载?

#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void LError();
bool CreateMainWindow(HINSTANCE hinst, int width, int height);

WNDCLASSEX MC;
HWND Hmain;

int APIENTRY WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR     lpCmdLine,
    int       nCmdShow) {
    MSG msg;
    if (!CreateMainWindow(hInstance, 800, 600)) {
        LError();
    }

    ShowWindow(Hmain, nCmdShow);
    UpdateWindow(Hmain);

    HACCEL hAccel = LoadAccelerators(hInstance, NULL);
    BOOL bRet = 0;
    while (bRet = GetMessage(&msg, nullptr, 0, 0))
    {
        if (-1 == bRet) break;
        if (!TranslateAccelerator(Hmain, hAccel, &msg))
        {
            if (!IsDialogMessage(Hmain, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }
    return msg.wParam;
}

void LError() {
    DWORD err = GetLastError();

    // Translate ErrorCode to String.
    LPTSTR Error = 0;
    if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        err,
        0,
        (LPTSTR)&Error,
        0,
        NULL) == 0)
    {
        MessageBox(NULL, TEXT("Error Translating"), TEXT("Error"), NULL);
    }
    if (Error = LPTSTR("The operation completed successefully")) {
        return;
    }
    MessageBox(NULL, Error, TEXT("GetCurrentDirectory Error"), MB_OK | MB_ICONWARNING);

    // Free the buffer.
    if (Error)
    {
        ::LocalFree(Error);
        Error = 0;
    }
}

bool CreateMainWindow(HINSTANCE hinst, int width, int height) {
    LPCSTR Cname = "MainWindow";
    MC.cbSize = sizeof(MC);
    MC.style = CS_HREDRAW | CS_VREDRAW;
    MC.style = 0;
    MC.lpfnWndProc = WndProc;
    MC.lpszMenuName = NULL;
    MC.lpszClassName = Cname;
    MC.cbWndExtra = NULL;
    MC.cbClsExtra = NULL;
    MC.hIcon = LoadIcon(NULL, IDI_WINLOGO);
    MC.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
    MC.hCursor = LoadCursor(NULL, IDC_ARROW);
    MC.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    MC.hInstance = HINSTANCE(hinst);
    if (!RegisterClassEx(&MC)) {
        return 0;
    }

    RECT dspl;
    GetWindowRect(GetDesktopWindow(), &dspl);

    Hmain = CreateWindow(TEXT("MainWindow"),
        LPCSTR("Calendar"),
        WS_OVERLAPPED,
        dspl.right - width, 0 ,
        width, height,
        (HWND)NULL,
        NULL,
        HINSTANCE(hinst),
        NULL);
    if (!Hmain) {
        return 0;
    }

    SetWindowLong(Hmain, GWL_EXSTYLE, WS_EX_LAYERED);
    SetLayeredWindowAttributes(Hmain, RGB(254, 254, 254), 150, LWA_ALPHA | LWA_COLORKEY);


    return 1;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
    HDC hDC;
    PAINTSTRUCT PS;
    RECT rect;
    switch (Msg) {

    case WM_PAINT:
        break;  

    case WM_KEYUP:
        switch(wParam) {
        case VK_ESCAPE:
            PostQuitMessage(NULL); break;
        }break;


    case WM_DESTROY:
        PostQuitMessage(NULL);
        break;

    default:
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    return 0;
}

1 个答案:

答案 0 :(得分:2)

摘自WM_PAINT文档:

  

如果应用程序处理此消息,则返回零。

删除WM_PAINT或对其进行处理:

case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps);
    EndPaint(hWnd, &ps);
    return 0;
}

否则,WndProc会不断收到WM_PAINT消息。或者,您可以输入:

case WM_PAINT: return DefWindowProc(hWnd, Msg, wParam, lParam);

DefWindowProc将调用BeginPaint/EndPaint来验证客户区。