在 WM_KEYDOW 消息中捕获 VK_UP 无效
catching VK_UP in WM_KEYDOW message not working
window 过程中的这段代码不起作用:
case WM_KEYDOWN:
switch(wParam)
{
case VK_UP:
MessageBox(NULL, L"key up", L"", MB_OK);
break;
default:
break;
}
我按向上箭头键,但未调用 MessageBox
。我错过了什么?
完整代码:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#ifdef UNICODE
#define STRSPLIT wcsrchr
#else
#define STRSPLIT strrchr
#endif
#define __FILENAME__ (STRSPLIT(TEXT(__FILE__), '/') ? STRSPLIT(TEXT(__FILE__), '/') + 1 : TEXT(__FILE__))
#define NAMEOF(s) TEXT(#s)
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
#include <windows.h>
#include <strsafe.h>
#include <CommCtrl.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void setUpScrollBar(HWND hwnd);
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename);
DWORD ShowLastError(LPWSTR lpszFunction, int line, LPWSTR filename);
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text);
void CreateTab(HWND hwnd);
HWND hTab;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR lpCmdLine, int nCmdShow) {
MSG msg;
WNDCLASSW wc = {0};
wc.lpszClassName = L"main window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassW(&wc);
HWND hWnd =
CreateWindowW(wc.lpszClassName, L"foo",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 330, 180, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
static int g_scrollY;
switch(msg)
{
case WM_CREATE:
CreateWindowW(L"Static", L"This is label 1...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 10, 130, 25, hwnd, (HMENU) 18, NULL, NULL);
CreateWindowW(L"Static", L"This is label 2...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 40, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 3...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 70, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 4...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 100, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 5...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 130, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 6...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 160, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 7...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 190, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
setUpScrollBar(hwnd);
break;
case WM_VSCROLL:
int action = LOWORD(wParam);
//HWND hScroll = (HWND)lParam;
int pos = -1;
if (action == SB_THUMBPOSITION || action == SB_THUMBTRACK) {
pos = HIWORD(wParam);
} else if (action == SB_LINEDOWN) {
pos = g_scrollY + 30;
} else if (action == SB_LINEUP) {
pos = g_scrollY - 30;
}
if (pos == -1)
break;
SCROLLINFO si = { 0 };
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS;
si.nPos = pos;
si.nTrackPos = 0;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);
pos = si.nPos;
POINT pt;
pt.x = 0;
pt.y = pos - g_scrollY;
HDC hdc = GetDC(hwnd);
LPtoDP(hdc, &pt, 1);
ReleaseDC(hwnd, hdc);
ScrollWindow(hwnd, 0, -pt.y, NULL, NULL);
g_scrollY = pos;
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_UP:
MessageBox(NULL, L"key up", L"", MB_OK);
break;
default:
break;
}
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
void setUpScrollBar(HWND hwnd)
{
RECT rc = { 0 };
GetClientRect(hwnd, &rc);
SCROLLINFO si = { 0 };
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = 220;
si.nPage = (rc.bottom - rc.top);
si.nPos = 0;
si.nTrackPos = 0;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
}
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename)
{
DWORD dw = ShowLastError(lpszFunction, line, filename);
ExitProcess(dw);
}
DWORD ShowLastError(LPWSTR lpszFunction, int line, LPWSTR filename)
{
#define MAX_DIGITS 16
DWORD dw = GetLastError();
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) +
lstrlen((LPCTSTR)lpszFunction) + 40 +
(line > 0 ? MAX_DIGITS : 0) +
(filename != NULL ? lstrlen(filename) : 0)) *
sizeof(TCHAR)
);
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with %d: %s"),
lpszFunction, dw, lpMsgBuf
);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
return dw;
}
您的消息泵格式不正确。您正在为无模式对话框(通过 CreateDialog
创建的 window)做一些事情,但是您的应用程序中没有这样的 window 类型。因此,您的一些消息被 IsDialogMessage
函数吞没了。
所以不是这个:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
这个:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
当我将您的代码更改为该代码时,会出现消息框。
window 过程中的这段代码不起作用:
case WM_KEYDOWN:
switch(wParam)
{
case VK_UP:
MessageBox(NULL, L"key up", L"", MB_OK);
break;
default:
break;
}
我按向上箭头键,但未调用 MessageBox
。我错过了什么?
完整代码:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#ifdef UNICODE
#define STRSPLIT wcsrchr
#else
#define STRSPLIT strrchr
#endif
#define __FILENAME__ (STRSPLIT(TEXT(__FILE__), '/') ? STRSPLIT(TEXT(__FILE__), '/') + 1 : TEXT(__FILE__))
#define NAMEOF(s) TEXT(#s)
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
#include <windows.h>
#include <strsafe.h>
#include <CommCtrl.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void setUpScrollBar(HWND hwnd);
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename);
DWORD ShowLastError(LPWSTR lpszFunction, int line, LPWSTR filename);
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text);
void CreateTab(HWND hwnd);
HWND hTab;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR lpCmdLine, int nCmdShow) {
MSG msg;
WNDCLASSW wc = {0};
wc.lpszClassName = L"main window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassW(&wc);
HWND hWnd =
CreateWindowW(wc.lpszClassName, L"foo",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 330, 180, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
static int g_scrollY;
switch(msg)
{
case WM_CREATE:
CreateWindowW(L"Static", L"This is label 1...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 10, 130, 25, hwnd, (HMENU) 18, NULL, NULL);
CreateWindowW(L"Static", L"This is label 2...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 40, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 3...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 70, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 4...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 100, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 5...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 130, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 6...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 160, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateWindowW(L"Static", L"This is label 7...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,
50, 190, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
setUpScrollBar(hwnd);
break;
case WM_VSCROLL:
int action = LOWORD(wParam);
//HWND hScroll = (HWND)lParam;
int pos = -1;
if (action == SB_THUMBPOSITION || action == SB_THUMBTRACK) {
pos = HIWORD(wParam);
} else if (action == SB_LINEDOWN) {
pos = g_scrollY + 30;
} else if (action == SB_LINEUP) {
pos = g_scrollY - 30;
}
if (pos == -1)
break;
SCROLLINFO si = { 0 };
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS;
si.nPos = pos;
si.nTrackPos = 0;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);
pos = si.nPos;
POINT pt;
pt.x = 0;
pt.y = pos - g_scrollY;
HDC hdc = GetDC(hwnd);
LPtoDP(hdc, &pt, 1);
ReleaseDC(hwnd, hdc);
ScrollWindow(hwnd, 0, -pt.y, NULL, NULL);
g_scrollY = pos;
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_UP:
MessageBox(NULL, L"key up", L"", MB_OK);
break;
default:
break;
}
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
void setUpScrollBar(HWND hwnd)
{
RECT rc = { 0 };
GetClientRect(hwnd, &rc);
SCROLLINFO si = { 0 };
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = 220;
si.nPage = (rc.bottom - rc.top);
si.nPos = 0;
si.nTrackPos = 0;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
}
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename)
{
DWORD dw = ShowLastError(lpszFunction, line, filename);
ExitProcess(dw);
}
DWORD ShowLastError(LPWSTR lpszFunction, int line, LPWSTR filename)
{
#define MAX_DIGITS 16
DWORD dw = GetLastError();
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) +
lstrlen((LPCTSTR)lpszFunction) + 40 +
(line > 0 ? MAX_DIGITS : 0) +
(filename != NULL ? lstrlen(filename) : 0)) *
sizeof(TCHAR)
);
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with %d: %s"),
lpszFunction, dw, lpMsgBuf
);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
return dw;
}
您的消息泵格式不正确。您正在为无模式对话框(通过 CreateDialog
创建的 window)做一些事情,但是您的应用程序中没有这样的 window 类型。因此,您的一些消息被 IsDialogMessage
函数吞没了。
所以不是这个:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
这个:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
当我将您的代码更改为该代码时,会出现消息框。