【问题标题】:C programming HWNDC 编程 HWND
【发布时间】:2017-06-10 22:05:40
【问题描述】:

当我编译我的代码时,应该打开一个窗口,但它没有。我创建了一个类、HWND 和应用程序处理程序;依然没有。

我有点新,很抱歉这个问题。

应用程序运行良好,没有错误,但窗口似乎没有出现。

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>


LRESULT CALLBACK myCallBack(HWND regularWnd, UINT message, WPARAM wparam, LPARAM lparam){
    switch(message){
    case 0x0201:
    printf("left Click");
    MessageBox(regularWnd, "Left Click", "event handler", MB_OK);
    break;
    case WM_CLOSE: 
    DestroyWindow(regularWnd);
    break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    default:
    DefWindowProc(regularWnd, message, wparam, lparam);
    break;
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE newHInstance, HINSTANCE prevHINSTANCE, LPSTR lpCmdLine, int cmdShow){

    WNDCLASSEX regularWndClass;

    regularWndClass.cbSize = sizeof(WNDCLASSEX);
    regularWndClass.cbWndExtra = 0;
    regularWndClass.cbClsExtra = 0;
    regularWndClass.style = 0;
    regularWndClass.lpszClassName = "regularWindowClass";
    regularWndClass.lpszMenuName = NULL;
    regularWndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+2);
    regularWndClass.lpfnWndProc = myCallBack;
    regularWndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    regularWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    regularWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    regularWndClass.hInstance = newHInstance;

    if(!RegisterClassEx(&regularWndClass) < 0){
        perror("Error Wnd class: ");
        exit(0);
    }

    HWND regularWnd;

    regularWnd = CreateWindowEx(WS_EX_CLIENTEDGE, "regularWindowClass", "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, newHInstance, NULL);

    if(regularWnd < 0){
        perror("window error : ");
        exit(0);
    }

    ShowWindow(regularWnd, cmdShow);
    UpdateWindow(regularWnd);

    MSG message;
    while(GetMessage(&message, NULL, 0, 0) > 0){
        TranslateMessage(&message);
        DispatchMessage(&message);
    }
    return message.wParam;
}

【问题讨论】:

  • 我认为CreateWindowEx() 不会设置errno。将其更改为使用GetLastError()FormatMessage()——但这只是一个提示;)
  • 建议大家仔细阅读MSDN上ShowWindow函数的文档:msdn.microsoft.com/en-us/library/windows/desktop/…
  • 不要使用perror,因为它会检查errno,Win32 不使用它

标签: c winapi hwnd


【解决方案1】:

直接错误在这一行:

DefWindowProc(regularWnd, message, wparam, lparam);

一个窗口过程应该返回一个LRESULTDefWindowProc 在必要时会这样做,但你不会传递它。将其更改为

return DefWindowProc(regularWnd, message, wparam, lparam);

您的窗口将按预期显示。

除此之外, 不使用errno,因此perror() 将不起作用。您必须使用GetLastError()FormatMessage() 来获取有意义的错误消息,并且使用WinMain()(强烈建议子系统windows),默认情况下您将没有控制台来显示它们......

最后,UpdateWindow() 是完全没有必要的。

【讨论】:

  • WinMain 只是用户提供的入口点。它本身并不控制程序在哪个子系统中运行。/SUBSYSTEM 链接器选项可以控制。
  • 我没有说“控制”。但是使用WinMain 清楚地表明这将被构建为“windows 子系统”。
  • "WinMain()(表示子系统windows)" - 这是错误的。 WinMain 只是一个符号。按照约定,这用于在 WINDOWS 子系统中运行的应用程序。
  • @IInspectable 如果您坚持理解它是错误的,那只是“错误”,而且这根本不是问题的重点我的提示:OP正在写一个 windows 程序,所以stdio 在没有准备的情况下将无法使用。
  • 这是一个无条件的陈述,是错误的。无需解释。并且由于它是您答案的一部分,因此我指出了它,以便您可以改进它。一种说法是,WinMain“是 [用于] 用户提供的基于 Windows 的图形应用程序的入口点的常规名称”
【解决方案2】:
LRESULT CALLBACK myCallBack(HWND regularWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    switch (message) {
        case 0x0201:
            printf("left Click");
            MessageBox(regularWnd, "Left Click", "event handler", MB_OK);
            return 0;
        case WM_CLOSE:
            DestroyWindow(regularWnd);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(regularWnd, message, wparam, lparam);
}

把你的窗口过程改成这个

另外,使用GetLastErrorFormatMessage 打印错误;不是perror,而是 C 标准库调用。这是一个如何使用这个功能的例子

https://msdn.microsoft.com/en-us/library/windows/desktop/ms680582(v=vs.85).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-27
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多