WinAPI 在按钮单击时没有任何反应

Posted

技术标签:

【中文标题】WinAPI 在按钮单击时没有任何反应【英文标题】:WinAPI nothing happens on button click 【发布时间】:2013-03-10 21:50:02 【问题描述】:

我的问题是:在下面的 C++ 代码中,为什么在应该从 WndProc1 调用 MessageBox 时单击按钮什么也不做?

P.S:编译后出现如下错误:

"C:\Windows\SysWOW64\ntdll.dll", Can't find or open PDB file.

代码:

#include <Windows.h>

LRESULT CALLBACK WndProc(
  _In_  HWND hwnd,
  _In_  UINT uMsg,
  _In_  WPARAM wParam,
  _In_  LPARAM lParam
);

LONG WINAPI WndProc1(
  _In_  HWND hwnd_button,
  _In_  UINT uMsg,
  _In_  WPARAM wParam,
  _In_  LPARAM lParam
);

//Точка входа в программу
int WINAPI WinMain
    (
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)

//Создаем класс окна
WNDCLASS WindowClass;

//Заполняем структуру 
WindowClass.style       = 0;
WindowClass.lpfnWndProc     = (WNDPROC)WndProc;
WindowClass.cbClsExtra      = 0;
WindowClass.cbWndExtra      = 0;
WindowClass.hInstance       = hInstance;
WindowClass.hIcon       = LoadIcon(hInstance,
                  (LPCTSTR)IDI_APPLICATION);
WindowClass.hCursor     = LoadCursor(NULL, IDC_ARROW);
WindowClass.hbrBackground   = (HBRUSH)(COLOR_WINDOW+1);
WindowClass.lpszMenuName    = 0;
WindowClass.lpszClassName   = TEXT("Class");

//Зарегистируем класс окна
RegisterClass(&WindowClass);

//Создаем переменную, в которой поместим идентификатор окна
HWND hWnd;

hWnd = CreateWindow(TEXT("Class"), TEXT("ClickTest"),
       WS_OVERLAPPEDWINDOW, 0, 0, 500, 300, NULL, NULL, hInstance, NULL); 

//Создаем кнопку
HWND hWnd_button;

hWnd_button = CreateWindow(TEXT("button"), TEXT("Click me"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
10, 10, 80, 30, hWnd, (HMENU)10000, hInstance, NULL);

//показать окно
ShowWindow(hWnd, nCmdShow);

//обновить содержимое окна
UpdateWindow(hWnd);

//Создадим переменную для храненния сообщений
MSG msg;

//Создадим цикл обработки сообщений
while(GetMessage(&msg, NULL,0 ,0))

    TranslateMessage(&msg);
    DispatchMessage(&msg);

return 0;


LONG WINAPI WndProc1(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)

switch (Message)
case WM_COMMAND:
    if(LOWORD(wparam)==10000)
    
        MessageBox(hwnd, TEXT("Button Pressed"), TEXT(""), 0);
    
    return 0;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

PAINTSTRUCT PS;
switch(message)

case WM_CREATE:
    break;
case WM_DESTROY:
    PostQuitMessage(0);
    break;
case WM_PAINT:
    BeginPaint(hWnd, &PS);
    EndPaint(hWnd, &PS);
    break;
default:
    return DefWindowProc(hWnd, message, wParam, lParam);

return 0;

现在工作,只是将按钮功能作为案例之一添加到WndProcWndProc1 已删除)

  LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lParam)
 
 PAINTSTRUCT PS;
 switch(message)
 
 case WM_CREATE:
    break;
 case WM_DESTROY:
    PostQuitMessage(0);
    break;
case WM_PAINT:
    BeginPaint(hWnd, &PS);
    EndPaint(hWnd, &PS);
    break;
case WM_COMMAND:
    if(LOWORD(wparam)==10000)
    
        MessageBox(hWnd, TEXT("Button Pressed"), TEXT(""), 0);
    
default:
    return DefWindowProc(hWnd, message, wparam, lParam);

return 0; 
  

最后一个新手问题:那么LRESULT CALLBACKLONG WINAPI 有什么区别?

【问题讨论】:

是的,很抱歉,我认为代码不是那么大(我不知道哪里出错了)并且 cmets 并不那么重要。 没关系,但有时用户可能会认为 cmets 是相关的。没问题,它不是那么大的代码,但在我看来,并非所有代码都与问题真正相关,尝试避免不相关的代码是一种很好的行为,因为用户可以更容易地发现问题。很高兴你找到了答案:) 关于你的最后一个问题。他们是一样的。 LRESULTLONG = long 是函数返回值。 CALLBACKWINAPI = __stdcall 这是一个 calling convention。 【参考方案1】:

WndProc上做这个修改:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

PAINTSTRUCT PS;
switch(message)

case WM_COMMAND:
    if(LOWORD(wParam)==10000)
    
        MessageBox(hWnd, TEXT("Button Pressed"), TEXT(""), 0);
    
    break;
case WM_CREATE:
    break;
// ...

我在WndProcswitch/case 中添加了WM_COMMAND

【讨论】:

【参考方案2】:

您希望如何调用WndProc1?它不与任何窗口类关联...您必须处理 WndProc 内的 WM_COMMAND(按钮以及其他常用控件,通过 WM_COMMAND 通知它们的它们的事件) .

【讨论】:

以上是关于WinAPI 在按钮单击时没有任何反应的主要内容,如果未能解决你的问题,请参考以下文章

按钮和组合框 WinAPI

WinAPI - 钩住鼠标

winapi查找网页对话框的子窗口标题(属性)

c ++ winapi - 子类化编辑控件 - 单击“Enter”时发出烦人的声音

WINAPI 光标在应用程序窗口上的点击位置

c++ winapi线程