如何在使用 windows.h 时避免使用全局变量 C++.
How to avoid using global variables when using windows.h C++
所以我有以下代码,我真的有两个问题:
如何避免使用全局变量来存储 以后使用?我显然无法向 WndProc 添加更多参数或 更改返回类型。我还能做些什么来存储新信息 以后?
为什么我不能使用LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
vector<string> *strings = reinterpret_cast<vector<string>*>(lpcs->lpCreateParams);
switch 语句之外的代码,然后引用指向 switch 语句内字符串向量的指针?我不明白为什么当我这样做时它超出了范围(我也不经常使用 switch 语句(。我还尝试在 switch 语句外部声明一个size
变量,以在 switch 语句中声明向量后存储向量的长度,但当然我遇到了同样的问题。
void Select(vector<string>& ret)
{
HINSTANCE hInstance = GetModuleHandle(NULL); //NULL = the current process
WNDCLASSW wc = { 0 };
MSG msg;
wc.lpszClassName = L"Selection1";
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.style = CS_DBLCLKS;
RegisterClassW(&wc);
CreateWindowW(wc.lpszClassName, L"Selection",
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, &ret);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
bool checked = true;
HWND text, button;
//hwnd is parent window
switch (msg) {
case WM_CREATE: {
text = CreateWindow("STATIC", "Selection:", WS_VISIBLE | WS_CHILD, 20, 20, 300, 25, hwnd, NULL, NULL, NULL);
button = CreateWindow("BUTTON", "Exit", WS_VISIBLE | WS_CHILD | WS_BORDER, 500, 500, 80, 25, hwnd, (HMENU)0, NULL, NULL);
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
vector<string> *strings = reinterpret_cast<vector<string>*>(lpcs->lpCreateParams);
int j = 23;
checkVectorSize = strings->size(); //checkVectorSize is a global variable
for (int i = 1; i != strings->size() + 1; i++)
{
cout << (*strings)[i - 1].c_str() << endl;
CreateWindowA("button", (*strings)[i - 1].c_str(),
WS_VISIBLE | WS_CHILD | BS_CHECKBOX | WS_OVERLAPPED,
20, j, 185, 35, hwnd, (HMENU)i,
NULL, NULL);
CheckDlgButton(hwnd, 0, BST_UNCHECKED);
j = j + 25;
}
break;
}
case WM_COMMAND: {
int i = wParam;
if (i == 0) //LOWORD(wParam)
{
for (int j = 0; j != checkVectorSize; j++)
{
if (IsDlgButtonChecked(hwnd, j + 1) == true)
{
checkResultIndexes.push_back(j);
//GetClassName(hwnd,)
//checkResult.push_back();
}
}
PostMessage(hwnd, WM_CLOSE, 0, 0);
//::MessageBeep(MB_ICONERROR);
//::MessageBox(hwnd, "Button was clicked", "", MB_OK);
break;
}
checked = IsDlgButtonChecked(hwnd, i);
if (checked) {
CheckDlgButton(hwnd, i, BST_UNCHECKED);
SetWindowTextW(hwnd, L"");
}
else {
CheckDlgButton(hwnd, i, BST_CHECKED);
SetWindowTextW(hwnd, L"");
}
break;
}
case WM_DESTROY: {
PostQuitMessage(0);
break;
}
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
您可以将Get
/SetWindowLongPtrW
与GWLP_USERDATA
标志一起使用,将任意数据与窗口相关联。在处理程序WM_CREATE
:
SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpter_cast<::LONG_PTR>(strings));
稍后检索存储值:
vector<string> *strings = reinterpret_cast<vector<string>*>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
assert(strings);
请注意,必须确保此指针指向的对象存活足够长的时间。
lParam
仅指WM_CREATE
消息中的LPCREATESTRUCT
。其他将其强制转换为该类别的尝试将失败,如读取访问冲突中所述。(见 https://learn.microsoft.com/en-us/windows/desktop/winmsg/wm-create(。 不要尝试将其转换为WM_CREATE
之外的该类型
相关文章:
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 当vector是tje全局变量时,c++中vector的内存管理
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 内联函数中具有内部链接的全局变量
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 全局变量 多读取器 一个写入器多线程安全?
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 不同作用域中的静态变量和全局变量
- C++ 在编译时具有函数计算全局变量
- 修改程序的入口点时未调用全局变量的构造函数
- 使用 std::ios_base::Init 正确初始化全局变量
- 为什么我的全局变量似乎没有变化?
- C ++程序如何返回我的数组或写入全局变量
- 为什么我的数组值与此处的全局变量不匹配?
- QT C++中对全局变量的未定义引用
- 跨多个类的全局变量而不会出现重定义错误?
- 赋予全局变量而不是局部变量优先级的函数 - (异常行为)
- C++线程不检测全局变量更改
- 在 elf 文件中查找全局变量的位置
- 包括一个类来定义全局变量参数 c++ :(