2013-01-16 65 views
0

我已經使用GetLastError()和​​確定已成功創建的按鈕。但是,當我運行該程序時它不可見。我最初在winMain中創建了按鈕,但在網上發現帖子說不要這樣做,所以我評論了它,並在WM_CREATE中添加了創作。請注意,所有的ID,等在一個resource.h文件中定義,並void ErrorExit()從MSDN採取使用GetLastError()和​​容易對一個相對較新的WINAPI程序員像我這樣做。我的代碼如下:WinAPI的Win32編程 - 按鈕不可見

#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(),做我需要調用這一點,如果我畫?

回答

0

WM_CREATE description我們讀取函數返回之前發送的消息。

因此WM_CREATE對於main_hwnd總是發生在tab0_hwnd被分配之前。

現在,讓我們看看你的代碼處理WM_CREATE

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

現在,那豈不是更好地產生錯誤信息,如果tab0_hwndNULL,而不是默默忽略錯誤?

這不一定是代碼的唯一問題,但如果沒有可編譯的示例,我不會繼續。

+0

我明白,這裏面就有一個問題,但不確定如何解決它除了增加if語句。 「compilable」btw是什麼意思?我可以詢問代碼中的其他問題嗎? – hherbol

+0

我的意思是我們可以編譯和測試的代碼,尤其是如果它不簡短並且不太可讀。提供'resource.h'可能就足夠了。對於其他問題,更好地創建新問題 - 評論中的長時間討論並非如此。 –

+0

順便說一下,*如果*在WinMain中創建按鈕有任何問題,那麼在'WinMain'中創建'SysTabControl'和其他所有東西都是錯誤的。如果你有一個真正的理由來執行'WM_CREATE'處理程序,那麼在該處理程序中執行* all *,即按照必要的順序在那裏創建選項卡控件,選項卡和按鈕。 (並且在'WM_CREATE'處理程序中執行*並不意味着*您必須將所有代碼放在一個巨大的開關中,將它分解爲新的函數!) –

0

WM_CREATE案例WndProc中創建按鈕的調用在tab0_hwnd窗口創建之前運行。 CreateWindow不會返回,直到它調用WndProcWM_CREATE窗口類,所以你的代碼的順序是這樣的:

  1. 創建主窗口:main_hwnd
  2. 運行在WndProc
  3. 的WM_CREATE情況下,代碼
  4. 創建標籤控件tab_hwnd
  5. 創建標籤控件tab0_hwnd

因此,您需要重新排序代碼,以便在創建標籤之後才能創建按鈕。

+0

我認爲'if()'語句阻止了按鈕的創建,直到創建了'tab0_hwnd'?你準確地提出了什麼樣的重新排序? – hherbol

+0

@hherbol - 你的意思是什麼? 'WM_CREATE'消息只會運行一次,所以沒有,直到它不會工作。我不知道爲什麼你的按鈕創建發生,'tab0_hwnd'應該總是'NULL'。要重新排序,您需要將按鈕創建移動到在「WinMain」中創建標籤之後,或者在「WM_CREATE」中創建標籤。 – shf301

+0

我最初試圖在處理程序中執行所有操作,但它不起作用。我在另一個線程[這裏]發佈舊代碼(http://stackoverflow.com/questions/14365518/winapi-win32-programming-tab-control-not-showing-up)。不知道爲什麼它不起作用,但這就是我在WinMain最初完成所有工作的原因。 – hherbol