0

我一直在研究一个选项卡控制程序,最近才在 StackOverflow 上发帖寻求帮助。目前程序运行如下:

  1. 开始于winMain,创建main_hwnd生成WM_CREATE并被wndProc调用
  2. tab_hwnd被创建为SysTabControl32
  3. tab0_hwnd, tab1_hwnd, ...,tab4_hwnd被创建
    • tab0_hwnd中,创建静态文本和按钮
  4. 返回winMain并被ShowWindow()调用main_hwndtab_hwnd并且tab0_hwnd
  5. 进入一个循环,直到程序关闭。

当程序运行时,一切都是可见的;但是,按钮无法正常工作。同时,我在使用搜索错误时GetLastError()FormatMessage()发现创建windows后tab#_hwnd(其中#=0,1,2,3和4),出现如下错误:

错误6:句柄无效

我不确定为什么会出现此错误以及为什么按钮不起作用。另一位用户在之前的帖子中提出了以下建议:

"WM_COMMAND被发送到直接父窗口,而不是祖父母,所以你要么必须子类化你的选项卡控件,要么让你的按钮将你的主窗口作为父窗口。- 安东·科瓦连科

编辑 1:我不确定如何按照 Anton Kovalenko 的建议对我的选项卡控件进行子类化。任何指向教程/注释解释的链接都将非常有帮助。

这是当前代码:

#define WIN32_LEAN_AND_MEAN
#pragma comment(lib, "comctl32.lib")

#define ID_FILE_EXIT                    101
#define ID_HELP_ABOUT                   102
#define ID_B_BLANK                      1001
#define ID_B_HOME                       1002
#define ID_B_SAVE                       1003

#include <strsafe.h>
#include <windows.h>
#include <CommCtrl.h>
#include <iostream>
#include <ShlObj.h>

HWND main_hwnd, tab_hwnd, tab0_hwnd, tab1_hwnd, tab2_hwnd, tab3_hwnd, tab4_hwnd;
HINSTANCE tab_hinst;
TCHAR HomePath[MAX_PATH*2], SavePath[MAX_PATH*2];
WNDCLASSEX wc;
bool success=FALSE;
MSG msg;
HWND button;
static HWND text;
TCITEM tie;
int focus = 0, NotifyCase = 0;

void ErrorExit(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); 
}
// Call with ErrorExit(TEXT("ANYTHINGHERE"));

    LRESULT CALLBACK WndProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch(Msg)
    {
        case WM_CREATE:
            {
                tab_hwnd = CreateWindowEx(
                    0,
                    "SysTabControl32",
                    "",
                    WS_CHILD,
                    CW_USEDEFAULT, CW_USEDEFAULT, 681, 338,
                    hwnd, NULL, tab_hinst, NULL);

                tab0_hwnd = CreateWindowEx(
                    0,
                    "SysTabControl32",
                    "",
                    WS_CHILD,
                    1, 22, 679, 315,
                    tab_hwnd, NULL, tab_hinst, NULL);

                //ErrorExit(TEXT("HERE")); //<--- This gives error 6: Handle invalid

                text = CreateWindow("Static","Home Directory",WS_CHILD | WS_VISIBLE,0,50,150,50,tab0_hwnd, 0, tab_hinst,0);
                text = CreateWindow("Static","C:\\",WS_CHILD | WS_VISIBLE,200,50,150,50,tab0_hwnd, 0, tab_hinst,0);
                button = CreateWindow("Button","Navigate to...", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,350,42,100,25,tab0_hwnd,(HMENU)ID_B_HOME,tab_hinst,0);  
                text = CreateWindow("Static","Save Directory",WS_CHILD | WS_VISIBLE,0,100,150,50,tab0_hwnd, 0, tab_hinst,0);
                text = CreateWindow("Static","C:\\",WS_CHILD | WS_VISIBLE,200,100,150,50,tab0_hwnd, 0, tab_hinst,0);
                button = CreateWindow("Button","Save to...", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,350,92,100,25,tab0_hwnd,(HMENU)ID_B_SAVE,tab_hinst,0);

                tab1_hwnd = CreateWindowEx(
                    0,
                    "SysTabControl32",
                    "",
                    WS_CHILD,
                    1, 22, 679, 315,
                    tab_hwnd, NULL, tab_hinst, NULL);

                tab2_hwnd = CreateWindowEx(
                    0,
                    "SysTabControl32",
                    "",
                    WS_CHILD,
                    1, 22, 679, 315,
                    tab_hwnd, NULL, tab_hinst, NULL);

                tab3_hwnd = CreateWindowEx(
                    0,
                    "SysTabControl32",
                    "",
                    WS_CHILD,
                    1, 22, 679, 315,
                    tab_hwnd, NULL, tab_hinst, NULL);

                tab4_hwnd = CreateWindowEx(
                    0,
                    "SysTabControl32",
                    "",
                    WS_CHILD,
                    1, 22, 679, 315,
                    tab_hwnd, NULL, tab_hinst, NULL);

                tie.mask = TCIF_TEXT;
                tie.pszText = "Paths";
                TabCtrl_InsertItem(tab_hwnd, 0, &tie);
                tie.pszText = "Output";
                TabCtrl_InsertItem(tab_hwnd, 1, &tie);
                tie.pszText = "Parameters";
                TabCtrl_InsertItem(tab_hwnd, 2, &tie);
                tie.pszText = "Configurations";
                TabCtrl_InsertItem(tab_hwnd, 3, &tie);
                tie.pszText = "Run";
                TabCtrl_InsertItem(tab_hwnd, 4, &tie);

                HMENU hMenu, hSubMenu;

                hMenu = CreateMenu();

                hSubMenu = CreatePopupMenu();
                AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
                AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "&Exit");

                hSubMenu = CreatePopupMenu();
                AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Help");
                AppendMenu(hSubMenu, MF_STRING, ID_HELP_ABOUT, "&About");

                SetMenu(hwnd, hMenu);
            }
            break;
        case WM_NOTIFY:
            switch(((LPNMHDR)lParam) ->code)
            {
                case TCN_SELCHANGING:
                    switch(TabCtrl_GetCurFocus(tab_hwnd))
                    {
                        case 0:
                            ShowWindow(tab0_hwnd,SW_HIDE);
                            break;
                        case 1:
                            ShowWindow(tab1_hwnd,SW_HIDE);
                            break;
                        case 2:
                            ShowWindow(tab2_hwnd,SW_HIDE);
                            break;
                        case 3:
                            ShowWindow(tab3_hwnd,SW_HIDE);
                            break;
                        case 4:
                            ShowWindow(tab4_hwnd,SW_HIDE);
                            break;
                        default:
                            return DefWindowProc(hwnd, Msg, wParam, lParam);
                            break;
                    }
                    break;
                case TCN_SELCHANGE:
                    switch(TabCtrl_GetCurFocus(tab_hwnd))
                    {
                        case 0:
                            ShowWindow(tab0_hwnd,SW_SHOW);
                            break;
                        case 1:
                            ShowWindow(tab1_hwnd,SW_SHOW);
                            break;
                        case 2:
                            ShowWindow(tab2_hwnd,SW_SHOW);
                            break;
                        case 3:
                            ShowWindow(tab3_hwnd,SW_SHOW);
                            break;
                        case 4:
                            ShowWindow(tab4_hwnd,SW_SHOW);
                            break;
                        default:
                            return DefWindowProc(hwnd, Msg, wParam, lParam);
                            break;
                    }
                    break;
                default:
                    return DefWindowProc(hwnd, Msg, wParam, lParam);
            }
            break;
        case WM_COMMAND:
            //MessageBox(tab0_hwnd,"HERE","OKAY",NULL);
            switch(LOWORD(wParam))
            {
                case ID_FILE_EXIT:
                    PostMessage(hwnd, WM_CLOSE, 0, 0);
                    break;
                case ID_HELP_ABOUT:
                    return MessageBox(0, "This program is an alteration of ...", "About", MB_OK);
                case ID_B_HOME:
                    if(BN_CLICKED == HIWORD(wParam)){
                        MessageBox(tab0_hwnd,"HERE","OKAY",NULL);
                    }
                    break;
                case ID_B_SAVE:
                    if(BN_CLICKED == HIWORD(wParam)){
                    }
                    break;
                case ID_B_BLANK:
                    break;
                default:
                    return DefWindowProc(hwnd, Msg, wParam, lParam);
            }
            break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
            break;  
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, Msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    InitCommonControls();
    tab_hinst = hInstance;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "Home";
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);

    main_hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        "Home",
        "The Home page",
        WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT, 700, 400,
        NULL, NULL, hInstance, NULL);

    if(main_hwnd == NULL) {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(main_hwnd, nCmdShow);
    ShowWindow(tab_hwnd,SW_SHOW);
    ShowWindow(tab0_hwnd,SW_SHOW);
    UpdateWindow(main_hwnd);

    do{
        PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    } while(msg.message!=WM_CLOSE && msg.message!=WM_QUIT);
    return msg.wParam;
}
4

0 回答 0