C++ 如何避免在使用windows.hc++;

C++ 如何避免在使用windows.hc++;,c++,visual-studio,winapi,switch-statement,global-variables,C++,Visual Studio,Winapi,Switch Statement,Global Variables,我有以下代码,我有两个问题: 如何避免使用全局变量来存储 以后用?显然,我无法向WndProc或 更改返回类型。我还能做些什么来存储新信息 以后用 为什么我不能使用LPCREATESTRUCT lpcs=reinterpret_cast(lParam); vector*strings=reinterpret_cast(lpcs->lpCreateParams) 在switch语句外编写代码,然后引用switch语句内字符串向量的指针?我不明白为什么我这样做时它超出了范围(我也不经常使用switc

我有以下代码,我有两个问题:

如何避免使用全局变量来存储 以后用?显然,我无法向WndProc或 更改返回类型。我还能做些什么来存储新信息 以后用

为什么我不能使用LPCREATESTRUCT lpcs=reinterpret_cast(lParam); vector*strings=reinterpret_cast(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);
void选择(向量和ret)
{
HINSTANCE HINSTANCE=GetModuleHandle(NULL);//NULL=当前进程
WNDCLASSW wc={0};
味精;
wc.lpszClassName=L“Selection1”;
wc.hInstance=hInstance;
wc.hbrBackground=(HBRUSH)颜色背景;
wc.lpfnWndProc=WndProc;
wc.hCursor=加载光标(0,IDC_箭头);
wc.style=CS_DBLCLKS;
注册分类(&wc);
CreateWindowW(wc.lpszClassName,L“Selection”,
WS|U重叠窗口| WS|U可见| WS|U系统菜单,
CW_usefault、CW_usefault、CW_usefault、CW_usefault、0、0、hInstance和ret);
while(GetMessage(&msg,NULL,0,0)){
翻译信息(&msg);
发送消息(&msg);
}
}
LRESULT回调WndProc(HWND HWND,UINT msg,
WPARAM WPARAM,LPARAM LPARAM){
bool checked=true;
HWND文本,按钮;
//hwnd是父窗口
开关(msg){
案例WM_创建:{
text=CreateWindow(“静态”、“选择:”,WS_可见| WS_子对象,20、20、300、25、hwnd、NULL、NULL、NULL);
button=CreateWindow(“按钮”、“退出”、WS|U可见| WS|U子项| WS|U边框、500、500、80、25、hwnd、(HMENU)0、NULL、NULL);
LPCREATESTRUCT lpcs=reinterpret_cast(lpram);
vector*strings=reinterpret_cast(lpcs->lpCreateParams);
int j=23;
checkVectorSize=strings->size();//checkVectorSize是一个全局变量
对于(int i=1;i!=strings->size()+1;i++)
{

cout您可以使用
Get
/
SetWindowLongPtrW
GWLP\u USERDATA
标志将任意数据与窗口关联。在
WM\u CREATE
处理程序中:

SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpter_cast<::LONG_PTR>(strings));
SetWindowLongPtrW(hwnd、GWLP_USERDATA、reinterpter_cast(strings));
要稍后检索存储值,请执行以下操作:

vector<string> *strings = reinterpret_cast<vector<string>*>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
assert(strings);
vector*strings=reinterpret_cast(GetWindowLongPtrW(hwnd,GWLP_USERDATA));
断言(字符串);

请注意,您必须确保此指针指向的对象能够存活足够长的时间。

lParam
WM\u CREATE
消息期间仅引用
LPCREATESTRUCT
。其他将其强制转换到该对象的尝试将失败,正如您描述的读取访问冲突。(请参阅)。不要试图将其转换为
WM\u CREATE

如何调用
Select
?调用
WM\u CREATE
的回调后,传递引用的向量是否会被构造?也许你应该尝试创建一个来向我们展示?“我也不经常使用switch语句”-如果你打算使用Win32,最好仔细阅读它们。当然,真正的解决方案不是使用Win32-如果你想创建Windows GUI应用程序,请使用C#。@edtheprogrammerguy我的程序在执行“读取访问冲突”时总是抛出异常@Someprogrammerdude调用WM_CREATE时,向量的元素将用于命名各个复选框。我永远不会理解我在这个网站上得到的所有反对票。所以第四个参数可以是任意数据?有没有办法在其他函数中使用数据?第三个参数应该是指向任意数据的指针。通常会创建某种windows上下文结构以及所有相关字段,并将指向此结构的指针存储为userdata。它可以随时从窗口句柄中检索。我的错误,打字错误。我遇到的一个问题是,我需要找出用户选中了哪些按钮,但我无法找出如何访问该信息在上,我只保存了我知道在全局向量中检查的索引。这个方法可以用来缓解这个问题吗?@Colebacha2您可以将该向量存储为每个窗口上下文的一部分,并在处理按钮消息时提取它。@Colebacha2它使您可以从任何地方访问数据,只要您有一个窗口句柄。我没有这样做我知道,谢谢你!