我是Win32 API的初学者。我正在尝试创建一个需要容器的小应用程序,但我遇到了问题。
在HTML中,我会告诉你我想要什么。它的代码如下:
div{width:120px; height:300px; display:block; overflow-y:auto;}
button{display:list-item;list-style:none; margin-bottom:3px;}
<div class="container">
<button>button 1</button>
<button>button 2</button>
<button>button 3</button>
<button>button 4</button>
<button>button 5</button>
<button>button 6</button>
<button>button 7</button>
<button>button 8</button>
<button>button 9</button>
<button>button 10</button>
<button>button 11</button>
<button>button 12</button>
<button>button 13</button>
<button>button 14</button>
</div>
我尝试使用以下代码在C ++中重复相同的显示:
#include <windows.h>
#include <string>
#include <vector>
const char *ClsName = "classname";
const char *WndName = "Windows";
HINSTANCE hInst;
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
hInst = hInstance;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProcedure;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_QUESTION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_PEN);
WndClsEx.lpszMenuName = MAKEINTRESOURCEA(109);
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInst;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_QUESTION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL);
// Find out if the window was created successfully
if (!hWnd) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
};
//classname
//classname
using namespace std;
LRESULT CALLBACK WndProcedure(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
static HWND ws[50], st, sd;
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0); break;
case WM_CREATE:
sd = CreateWindow(ClsName, NULL, WS_CHILD | WS_VSCROLL |WS_HSCROLL| WS_BORDER | WS_VISIBLE, 10, 10, 200, 600, hwnd, NULL, hInst, NULL);//Container
for (int i = 0; i < 114; i++) {
ws[i] = CreateWindow("Button", ("Button" + to_string(i)).c_str(), WS_VISIBLE | WS_BORDER | WS_CHILD, 10, 25*i + 10, 150, 20, sd, (HMENU)(i + 1), hInst, NULL); //Buttons
};
break;
default: return DefWindowProc(hwnd, msg, wparam, lparam); break;
}
}
使用这段代码,我得到一个在主窗口中无限重复的容器。
这是结果的屏幕截图;
我不明白结果。似乎我使用了一个循环,但我没有。
答案 0 :(得分:2)
似乎我使用了循环,但我没有。
实际上,你做到了。您的WM_CREATE
消息处理程序中有递归循环。
您的WinMain()
来电CreateWindow()
来创建初始ClsName
窗口,然后您的WM_CREATE
处理程序调用{{1}}来创建另一个 CreateWindow()
窗口(对其邮件使用相同的ClsName
)。当第二个窗口收到WndProcedure()
时,您正在调用WM_CREATE
来创建另一个 CreateWindow()
窗口。还有另一个ClsName
窗口,依此类推。
请勿在早期ClsName
窗口的ClsName
内创建新的WM_CREATE
窗口。您已定义了ClsName
类名,但您没有注册或使用它。也许你打算这样做。或者,对容器使用标准STATIC
control。
此外,您的WndName
邮件处理程序还有另一个错误。它创建了114个子按钮,但是将它们存储在一个只能容纳50 WM_CREATE
s的静态数组中。因此,您有一个缓冲区溢出会破坏内存。
答案 1 :(得分:0)
好的,首先,我认为你的意思是WM_CREATE(不是VM_CREATE) - 你发布了实际的代码吗?因为我怀疑这是否有效。
其次,WM_CREATE是您在调用CreateWindow后由Windows发送给您的消息。在这里看到doco: https://msdn.microsoft.com/en-us/library/windows/desktop/ms632619(v=vs.85).aspx
在你的情况下,你将创建一个无限循环的窗口创建,然后是通知消息。