WinAPI - 获取用于绘图的可滚动框架
WinAPI - get a scrollable frame for drawing
我正在编写一种算法,该算法通过较冷的身体计算后续工作作为夏季工作。算法本身已经完成,我开始研究制作一个简单的 C++GUI,您可以在其中为特定的冷却器组合创建连续性,并能够事先查看它。这不是我以前做过的任何事情。
我有一些相当简单的工作,现在我直接在主窗口上绘制序列的外观。 在同一个主窗口中将其绘制到可滚动的"框架"中有什么困难吗? 现在,更大的组合太大而无法容纳在同一屏幕上,仅仅使窗口更大是不够的。 感谢您的任何帮助!
我尝试使用样式"WS_VSCROLL"制作静态并使用"hdc = GetDC(hWndNewStatic)",我花了一小段时间来处理绘图,然后它再次不起作用。滚动条不起作用。
示例程序图片
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex = {};
wcex.cbClsExtra = 0;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbWndExtra = 0;
wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE (IDI_ICON));
wcex.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE (IDI_ICON));
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = TEXT("WinApp");
wcex.lpszMenuName = NULL;
wcex.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL, TEXT("RegisterClassEx Failed!"), TEXT("Error"), MB_ICONERROR);
return EXIT_FAILURE;
}
HWND hWnd = CreateWindow(
TEXT("WinApp"), TEXT("SeqGen"),
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT,
NULL, NULL, hInstance, NULL
);
if (!hWnd)
{
MessageBox(NULL, TEXT("CreateWindow Failed!"), TEXT("Error"), MB_ICONERROR);
return EXIT_FAILURE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
hdc = GetDC(hWnd);
// Messages
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (IsDialogMessage(hWnd, &msg))
{}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return EXIT_SUCCESS;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPCSTR moduleValue;
static int index {};
static unsigned module {0};
static bool draw {false};
switch (msg)
{
case WM_CREATE:
hWndStatic = CreateWindow(
TEXT("Static"), TEXT("Tube rows"),
WS_CHILD | WS_VISIBLE,
30, 20, 100, 24,
hWnd, NULL, NULL, NULL
);
hWndStatic = CreateWindow(
TEXT("Static"), TEXT("Water passes"),
WS_CHILD | WS_VISIBLE,
130, 20, 100, 24,
hWnd, NULL, NULL, NULL
);
hWndStatic = CreateWindow(
TEXT("Static"), TEXT("Multiples"),
WS_CHILD | WS_VISIBLE,
230, 20, 100, 24,
hWnd, NULL, NULL, NULL
);
hWndrr = CreateWindowEx(
WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""),
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
30, 50, 50, 24,
hWnd, NULL, NULL, NULL
);
hWndvv = CreateWindowEx(
WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT(""),
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
130, 50, 50, 24,
hWnd, NULL, NULL, NULL
);
hWndN = CreateWindowEx(
WS_EX_CLIENTEDGE, TEXT("Edit"), TEXT("0"),
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
230, 50, 50, 24,
hWnd, NULL, NULL, NULL
);
hWndList = CreateWindow(
TEXT("ListBox"), TEXT(""),
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL | WS_BORDER | LBS_NOTIFY,
20, 150, TEXTBOX_WIDTH, TEXTBOX_HEIGHT,
hWnd, (HMENU) LST_RESULT, NULL, NULL
);
hWndCreateall = CreateWindow(
TEXT("Button"), TEXT("Create all DIR"),
WS_CHILD | WS_VISIBLE,
50, 90, 100, 24,
hWnd, (HMENU) BTN_CREATEALL, NULL, NULL
);
hWndButton = CreateWindow(
TEXT("Button"), TEXT("Create DIR"),
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
200, 90, 100, 24,
hWnd, (HMENU) BTN_CREATE, NULL, NULL
);
break;
case WM_COMMAND:
switch (HIWORD(wParam))
{
case LBN_SELCHANGE:
if (LOWORD(wParam) == LST_RESULT)
{
index = SendMessage(hWndList, LB_GETCURSEL, 0, 0);
if (index >= 0)
{
module = 0;
moduleValue = (to_string(module).c_str());
SetWindowText(hWndStaticModule, moduleValue);
draw = true;
RedrawWindow(hWnd, 0, 0, RDW_INVALIDATE);
}
}
break;
case BN_CLICKED:
switch (LOWORD(wParam))
{
case BTN_CREATE:
--stuff for creating combination--
break;
case BTN_CREATEALL:
--stuff for creating all possible combination--
break;
}
break;
default:
break;
}
break;
case WM_PAINT:
if (draw)
{
--function for drawing stuff on main window--
draw = false;
}
UpdateWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(EXIT_SUCCESS);
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return FALSE;
}
你需要大量的代码来实现你需要的东西,我只能给你一个所需组件的理论解释。
-
面板类。面板需要自己的窗口类和自己的窗口程序。面板进程应该处理
WM_VSCROLL
,也许WM_HSCROLL
,手动设置新的滚动值,并用SetScrollPos
并将其存储在某个状态变量中。您的WM_*SCROLL
处理程序现在有两个选项:- 呼叫
InvalidateRect
,让WM_PAINT刷新整个面板。 - 调用
ScrollWindow
以移动实际图形,然后调用UpdateWindow
以刷新未覆盖的区域。
- 呼叫
-
面板的油漆算法。您应该像往常一样对绘制模型
WM_PAINT
做出反应,但 y 坐标必须通过滚动状态变量移动。您有以下几种选择:- 重绘整个窗口。
- 在屏幕外的 HDC 上绘制新窗口内容,然后在整个窗口上绘制比特布利特。
- 重绘未覆盖区域(请参阅上一点关于
ScrollWindow
)
- 主窗口上面板的实例。主要胜利将面板分配为子窗口,就像您为其他控件所做的那样,还指定
WS_VSCROLL
(和WS_HSCROLL
?)并根据文档大小使用SetScrollInfo
配置滚动大小。主赢家还需要对WM_SIZE
做出反应,以调整面板的大小(MoveWindow
),给它一个新的尺寸。计算新大小时,会从主赢的客户区中减去您喜欢的填充。
每一点最终都需要进一步的谷歌搜索和发布在SO上。
你也可以考虑用OpenGL,DirectX或GDI+绘图(这反过来可能会打开很多其他问题)。
相关文章:
- 使用一个考虑到std::map中键值的滚动或换行的键
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- catch框架有没有办法比较流或文件
- QScrollArea:由垂直滚动条引起的水平滚动条
- 跟踪滚动条上的鼠标事件
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 使用Qt框架在c ++类中创建API调用
- 如何在ECS框架中更新组件数据和通知系统
- VSCode IntelliSense无法识别SDL框架的SDL_image扩展库
- 用于C++的静态二进制检测或二进制重写工具和框架
- 如何在不使用滚动条的情况下使视图更改
- GoogleMock是否仍然打算与任何测试框架一起使用?
- 如何为对象生成滚动效果?
- 如何模拟不同边数的骰子滚动?
- 带有框架的 QGraphicsTextItem 的 QPropertyAnimation 会使文本抖动
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- 如何初始化升压滚动窗口累加器?
- 实现包含多个 QQuickPaintedItems 的 QQuickView 的滚动
- WinAPI - 获取用于绘图的可滚动框架
- 使用Qt动画框架的QPixmap的断断续续的滚动