【发布时间】:2017-04-20 00:26:38
【问题描述】:
在窗口 API 中,我有一个弹出菜单,其中分别包含 3 项“Line”、“Circle”和“Exit”。
我的程序是让用户选择要绘制的形状,然后获取点、参数(即线的起点和终点,...)。这是我目前编写的部分代码。
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
HMENU hMenu;
POINT point;
HDC hdc;
hdc = GetDC(hwnd);
static int x1, y1,x2,y2,count = 0;
switch (msg) {
case WM_LBUTTONDOWN:
count++;
if (count == 1)
{
x1 = LOWORD(lParam);
y1 = HIWORD(lParam);
}
else
{
x2 = LOWORD(lParam);
y2 = HIWORD(lParam);
// I think the problem goes here, it never execute else part
//even if global_ID ==2, Am I missing something?
if (global_ID == 1)//Line
{DirectMethod(hdc, x1, y1, x2, y2, RGB(0, 0, 0));}
else if (global_ID == 2)//Circle
{Ellipse(hdc, x1, y1, x2, y2);}
count = 0;
}
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDM_FILE_LINE:
global_ID = 1;
break;
case IDM_FILE_CIRCLE:
global_ID = 2;//Global Variable
break;
case IDM_FILE_QUIT:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_RBUTTONUP:
point.x = LOWORD(lParam);
point.y = HIWORD(lParam);
hMenu = CreatePopupMenu();
ClientToScreen(hwnd, &point);
AppendMenuW(hMenu, MF_STRING, IDM_FILE_LINE, L"&line");
AppendMenuW(hMenu, MF_STRING, IDM_FILE_CIRCLE, L"&Circle");
AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL);
AppendMenuW(hMenu, MF_STRING, IDM_FILE_QUIT, L"&Quit");
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL);
DestroyMenu(hMenu);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
我想要做的是,基于选定的菜单项(Line、Circle、...)我执行特定的代码段,这也取决于从用户获得鼠标点击 (WM_LBUTTONDOWN)。
例如: 如果用户选择“线”,我应该用两点来画那条线。
【问题讨论】:
-
您的实际问题是什么?您的代码已经在检测选择了哪个菜单项,这是由
WM_COMMAND消息报告的。那么,您的问题只是收集用户输入?例如,您可以让WM_COMMAND处理程序设置一个标志,指示所需坐标的编号,然后让您的WM_LBUTTONDOWN/UP处理程序保存坐标,直到达到该编号。您遇到的实际问题是什么? -
@RemyLebeau 问题是当一个菜单项被选中时,我更改“global_ID”值以知道选择了哪个菜单项,但在“WM_LBUTTONDOWN”内它“总是”执行 if 语句,从不执行 else部分,我已经调试了该代码,并且“global_ID”设置为“2”。我的意思是它假设执行“else”部分,但它总是执行“if”部分
-
您应该在问题中说明这些细节。鉴于
global_ID不是WndProc()的本地变量,您所描述的内容应该是不可能的,因此WM_COMMAND分配的任何值都将传递给后续的WM_LBUTTONDOWN。但是,您的代码中存在逻辑漏洞:1)即使您不应该计数鼠标点击,您也会计数。当您设置global_ID时,您不会将count重置为0; 2) 当global_ID不是 1 或 2 时,WM_LBUTTONDOWN根本不应该做任何事情; 3)你没有在调用DirectMethod()/Ellipse()后重置global_ID... -
... 和 4) 您的
WM_LBUTTONDOWN缺少必需的break语句,因此每条鼠标按下消息都会传递到WM_COMMAND代码。 -
您在
WM_LBUTTONDOWN处理程序末尾缺少break;。
标签: c++ windows user-interface winapi win32gui