計一次Win32 api程式顯示混亂問題的除錯經歷

流光溢彩_lxy發表於2024-07-09

背景:短學期任務,做一個his系統,老師是沒有要求gui的,我閒的沒事幹就打算寫一個gui,但是mfc、qt、unity每一個熟悉的,所以就直接用了win32 api手寫gui~~(我太難了,我發誓以後再也不手寫gui了)~~。然後我就想到了子視窗切換的方式來顯示不同的介面(好處在於,每個子介面直接呼叫現成api,我只需要規劃gui然後把控制元件搬進去,減少維護量,不然就要手寫控制元件,~~然後短學期就做不完了~~)。

問題:除錯的時候發現點選第一個完全沒問題,然後第一次點第二個有顯示但是會卡住,顯示也是錯誤的;但是先點“患者”再點“醫生”就是可以的

計一次Win32 api程式顯示混亂問題的除錯經歷 計一次Win32 api程式顯示混亂問題的除錯經歷 計一次Win32 api程式顯示混亂問題的除錯經歷

(前兩個是正常的;後面那個是錯的,顯示介面混了)

想法:起初以為是切換子視窗(ShowWindow實現)的時候切換錯了,但是仔細看了程式碼,子視窗切換並沒有問題;然後就想單步除錯,但是由於Win32程式中回撥函式的特殊性,在窗體回撥函式中除錯是不行的 (gdb和vs的偵錯程式都試過,不行),於是我就用宏定義加MessageBox的方式替代了單步除錯,只需在程式前面加上如下宏定義,然後在所需之處呼叫 LOG 宏即可,如果不想顯示訊息框,註釋#define __DEBUG即可。

#define _STR(x) _VAL(x)
#define _VAL(x) #x

#define __DEBUG
#ifdef __DEBUG
#define LOG MessageBox(NULL, _T(_STR(__LINE__)), _T("DEBUG"), MB_OK)
#else
#define LOG
#endif

結果:home_frame = CreateWindow(_T("home_frame"), _T("home_frame"), WS_CHILD | WS_VISIBLE, 0, 0, window_width, window_height, hWnd, NULL, hInst, NULL);這一段程式碼呼叫了兩次,導致有兩個相同內容不同控制代碼的窗 口,home_frame的值是最後一次呼叫的控制代碼,但是微軟好像把第一次生成的視窗置於頂層;同時在視窗回撥函式中第一個按鈕對應的ShowWindow中的HWND控制代碼是回撥函式形參給的,也即實際視窗的控制代碼,而後兩個對應的ShowWindow中的視窗控制代碼是home_frame(因為程式碼重複多,所以這裡用了copilot,沒仔細檢查),這也就導致了視窗顯示的混亂。

最後還是想說,copilot在提示詞不全,資訊少的情況下,犯錯的機率還是很大的,所以最好生成完進行全面檢查,以減少這樣的迷之bug。。。。

相關文章