【问题标题】:WinAPI win32 Programming - Button not visibleWinAPI win32 编程 - 按钮不可见
【发布时间】:2013-01-16 18:00:55
【问题描述】:

我已使用GetLastError()FormatMessage() 确定按钮已成功创建。但是,当我运行程序时它不可见。我最初在 winMain 中创建了按钮,但在网上发现帖子说不要这样做,所以我将其注释掉并将其添加到 WM_CREATE。请注意,所有 ID 等都在 resource.h 文件中定义,void ErrorExit() 取自 MSDN,以便在像我这样相对较新的 winApi 程序员上轻松使用 GetLastError()FormatMessage()。我的代码如下:

#define WIN32_LEAN_AND_MEAN
#define _WIN32_IE 0x0900
#define _WIN32_WINNT 0x0900

#include <strsafe.h>
#include <windows.h>
#include <CommCtrl.h>
#include <iostream>
#include <ShlObj.h>
#include <cstring>
#include "resource.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); 
}

// Step 4: The Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch(Msg)
    {
        case WM_CREATE:
            {
                if(tab0_hwnd!=NULL)
                    button = CreateWindow("Button","Navigate to...", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,350,42,100,25,tab0_hwnd,(HMENU)ID_B_HOME,(HINSTANCE)GetWindowLong(tab0_hwnd, GWL_HINSTANCE),0);
                /*if(tab0_hwnd!=NULL)
                    button = CreateWindow("Button","Save to...", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,350,92,100,25,tab0_hwnd,(HMENU)ID_B_SAVE,(HINSTANCE)GetWindowLong(tab0_hwnd, GWL_HINSTANCE), NULL);
                */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:
            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);
                    //return DefWindowProc(hwnd2,0,0,0);
                case ID_B_HOME:
                    MessageBox(tab0_hwnd,"HERE","OKAY",NULL);
                    break;
                case ID_B_SAVE:
                    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)
{
    tab_hinst = hInstance;

    //Step 1: Registering the Window Class
    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);

    // Step 2: Creating the Window
    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);

    tab_hwnd = CreateWindowEx(
        0,
        "SysTabControl32",
        "",
        WS_CHILD|WS_CLIPSIBLINGS,
        CW_USEDEFAULT, CW_USEDEFAULT, 681, 338,
        main_hwnd, NULL, tab_hinst, NULL);

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

    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|WS_CLIPSIBLINGS,
        1, 22, 679, 315,
        tab_hwnd, NULL, tab_hinst, NULL);

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

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

    tab4_hwnd = CreateWindowEx(
        0,
        "SysTabControl32",
        "",
        WS_CHILD|WS_CLIPSIBLINGS,
        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);

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

    ShowWindow(main_hwnd, nCmdShow);
    ShowWindow(tab_hwnd, nCmdShow);
    ShowWindow(tab0_hwnd,nCmdShow);
    UpdateWindow(main_hwnd);
    UpdateWindow(tab_hwnd);
    UpdateWindow(tab0_hwnd);
    // Step 3: The Message Loop
    do{
        PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE);
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&msg);
        /* Send message to WindowProcedure */
        DispatchMessage(&msg);
    } while(msg.message!=WM_CLOSE && msg.message!=WM_QUIT);
    return msg.wParam;
}

我也很好奇UpdateWindow(),不画画还需要打这个吗?

【问题讨论】:

    标签: c windows winapi


    【解决方案1】:

    WM_CREATE description,我们读到消息在函数返回之前发送

    因此WM_CREATE for main_hwnd 总是在分配tab0_hwnd 之前发生。

    现在让我们看看你的代码处理WM_CREATE

    if(tab0_hwnd!=NULL)
       /* you would create the button here, but it does not happen. */
    

    现在,如果tab0_hwndNULL,而不是默默地忽略错误,不是更好吗?

    这不一定是代码的唯一问题,但如果没有可编译的示例,我不会更进一步。

    【讨论】:

    • 我知道那里有问题,但除了添加 if 语句之外,不确定如何解决它。顺便说一句,“可编译”是什么意思?请问代码中的其他问题可以吗?
    • 我的意思是我们可以编译和测试的代码,特别是如果它不简短且不太可读的话。提供resource.h 可能就足够了。对于其他问题,最好创建新问题——在 cmets 中进行长时间的讨论不适合。
    • 顺便说一句,如果WinMain 中创建按钮有什么问题,在SysTabControlWinMain 中创建其他所有内容也会有问题.如果您有真正的理由这样做WM_CREATE 处理程序,那么在该处理程序中执行all,即按必要的顺序在那里创建选项卡控件、选项卡和按钮。 (并且在WM_CREATE 处理程序中执行此操作并不意味着您必须将所有代码都放在一个巨大的开关中。将其拆分为新功能!)
    • 我最初尝试在处理程序中完成所有操作,但没有成功。我刚刚在另一个线程here 中发布了我的旧代码。我不确定那个问题是什么。在当前代码中,选项卡和窗口有效;但是在旧代码中,它们甚至都不会显示。 (我直接在文件中添加了资源,所以编译旧代码不需要resource.h)
    【解决方案2】:

    WndProcWM_CREATE 案例中创建按钮的调用在创建tab0_hwnd 窗口之前运行。 CreateWindow 不会返回,直到它使用 WM_CREATE 为窗口类调用 WndProc 所以你的代码顺序是这样的:

    1. 创建主窗口:main_hwnd
    2. 运行WndProc的WM_CREATE情况下的代码
    3. 创建标签控件tab_hwnd
    4. 创建标签控件tab0_hwnd

    因此,您需要对代码重新排序,以便在创建选项卡之前不会创建按钮。

    【讨论】:

    • 我认为if() 语句阻止按钮被创建,直到tab0_hwnd 被创建?您究竟建议重新订购什么?
    • @hherbol - 直到你是什么意思? WM_CREATE 消息只会运行一次,所以没有直到 - 它永远不会工作。我不确定为什么您的按钮创建会发生,tab0_hwnd 应该始终是NULL。要重新排序,您需要将按钮创建移动到在WinMain 中创建选项卡之后,或者在WM_CREATE 中创建选项卡。
    • 我最初尝试在处理程序中完成所有操作,但没有成功。我在另一个线程here 中发布了旧代码。不知道为什么它不起作用,但这就是我最初在 WinMain 中做所有事情的原因。
    • 我有一个简单的问题。是否可以在没有WS_CHILDNULL 作为父窗口的情况下创建一个窗口,然后强制它成为另一个窗口的子窗口?或者必须将其声明为子级。
    【解决方案3】:

    也许你不见了WS_VISIBLE?它是必需的,否则您将看不到它。

    【讨论】:

    猜你喜欢
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 2012-06-15
    • 2021-09-16
    • 1970-01-01
    相关资源
    最近更新 更多