gpt4 book ai didi

c++ - 在 WM_COMMAND win32 GUI C++ 中处理 WM_LBUTTONDOWN 和 WM_LBUTTONUP

转载 作者:行者123 更新时间:2023-11-28 04:01:44 28 4
gpt4 key购买 nike

我正在创建一个带有如下下拉列表的窗口:

DropDown List

如果我单击前四个选项中的任何一个,包括它们的子选项,那么我想处理该选项。问题是我需要在这些选项中使用 WM_LBUTTONDOWNWM_LBUTTONUP 和其他类似的东西,但不知道如何使用。

我不知道在 case WM_COMMAND 中做什么来处理所有这些选项,所以这是我的 WindowProcedure:

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_LBUTTONDOWN
case WM_CREATE:
AddMenu(hwnd);
break;

case WM_COMMAND:

switch(wParam)
{
case Line_DDA:
break;
case Line_Midpoint:
break;
case Line_Parametric:
break;

case Ellipse_Direct:
break;
case Ellipse_Polar:
break;
case Ellipse_Midpoint:
break;

case Line_Clipping:
break;

case Convex_Filling:
break;

case Load_File:
break;

case Save_File:
break;
}
break;

case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}

这是 AddMenu():

void AddMenu(HWND hwnd)
{
hMenu = CreateMenu();
HMENU hSubMenu = CreateMenu();
HMENU hLineMenu = CreateMenu();
HMENU hEllipseMenu = CreateMenu();

AppendMenu(hLineMenu, MF_STRING, Line_DDA, "DDA");
AppendMenu(hLineMenu, MF_STRING, Line_Midpoint, "Midpoint");
AppendMenu(hLineMenu, MF_STRING, Line_Parametric, "Parametric");

AppendMenu(hEllipseMenu, MF_STRING, Ellipse_Direct, "Direct");
AppendMenu(hEllipseMenu, MF_STRING, Ellipse_Polar, "Polar");
AppendMenu(hEllipseMenu, MF_STRING, Ellipse_Midpoint, "Midpoint");

AppendMenu(hSubMenu, MF_POPUP, (UINT_PTR)hLineMenu, "Line");
AppendMenu(hSubMenu, MF_POPUP, (UINT_PTR)hEllipseMenu, "Ellipse");
AppendMenu(hSubMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hSubMenu, MF_STRING, Line_Clipping, "Line Clipping");
AppendMenu(hSubMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hSubMenu, MF_STRING, Convex_Filling, "Convex Filling");
AppendMenu(hSubMenu, MF_SEPARATOR, NULL, NULL);
AppendMenu(hSubMenu, MF_STRING, Load_File, "Load");
AppendMenu(hSubMenu, MF_STRING, Save_File, "Save");

AppendMenu(hMenu, MF_POPUP,(UINT_PTR)hSubMenu , "Draw");

SetMenu(hwnd, hMenu);
}

最佳答案

Remy Lebeau 的评论指出了正确的方向。让我们更具体一些。

在事件驱动编程中,您通常需要了解过去发生的事情才能决定现在要做什么。当事件发生时,您需要知道事件是什么(例如,WM_LBUTTONDOWN)当前状态。

对于您的程序,我们需要跟踪一些不同的东西,所以让我们将它们捆绑到一个结构中。

struct State {
enum { Idle, WaitingForPoint0, WaitingForPoint1, DrawIt } action;
DrawType type; // e.g., Line_DDA, Line_Midpoint, Ellipse_Direct, etc.
POINT points[2];
};

您需要某种方式将此 State 的实例与窗口的每个实例相关联。现在,我们只是将它设为一个全局变量,并假设您的程序中只有这种类型的窗口。

State g_state = {Idle};

当用户从菜单中选择一个绘图选项时,您更新当前状态。例如:

case Line_DDA:
g_state.action = WaitingForPoint0;
g_state.type = LineDDA;
break;

case Line_Midpoint:
g_state.action = WaitingForPoint0;
g_state.type = Line_Midpoint;
break;

// and so on

当用户按下按钮时,我们必须检查当前状态才能知道要做什么。

case WM_LBUTTONDOWN:
switch (g_state.action) {
case Idle: // just ignore the click
break;
case WaitingForPoint0:
g_state.points[0].x = GET_X_LPARAM(lParam);
g_state.points[0].y = GET_Y_LPARAM(lParam);
g_state.action = WaitingForPoint2;
break;
case WaitingForPoint1:
g_state.points[1].x = GET_X_LPARAM(lParam);
g_state.points[1].y = GET_Y_LPARAM(lParam);
g_state.action = DrawIt;
InvalidateRect(hWnd, NULL, TRUE);
break;
}
return 0;

最后,当窗口需要更新时,我们检查它的状态以确定那里显示的是什么形状。

case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
if (g_state.action == DrawIt) {
switch (g_state.type) {
case Line_DDA:
YourDrawLineDDA(hdc, g_state.points[0], g_state.points[1]);
break;
case Line_Midpoint:
YourDrawLineMidpoint(hdc, g_state.points[0], g_state.points[1]);
break;
// and so on
}
}
EndPaint(hwnd, &ps);
return 0;

这可能会变得非常冗长,但它说明了您想要做的事情的基本要素。您当然可以考虑让这种类型的代码更加简洁、优雅和可扩展。

关于c++ - 在 WM_COMMAND win32 GUI C++ 中处理 WM_LBUTTONDOWN 和 WM_LBUTTONUP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59416816/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com