My cutted down TestCode:
Just compile the source and try to close the programm (using the Window-Close-Button in the MainWindow). Normaly a MessageBox should be shown now; but this does not happens here (Windows 8.1 x64). You can bring the MessageBox to front, when using 'Alt + Tab'. Pressing 'Alt + F4' fires a CloseEvent, so the MessageBox will be shown correctly.
Now just remove the 'CASE #WM_PAINT' at line 251, inside 'WIndowCallback_Main()' and try to close the window again by pressing the Window-Close-Button; it seems to work fine.
So, if there are no other problems with my source, why does it happens?
If you have any suggestions to get my source more professional like professional C/C++ code, please let me know - thanks!
Code: Select all
; PureBasic 5.21 LTS (Windows - x86 and x64)
; ==============================================================
;
; COMPILER OPTIONS:
; [ ] Enable inline ASM support
; [x] Create unicode executable
; [ ] Create threadsafe executable
; [ ] Enable OnError lines support
; [x] Enable XP skin support
; [ ] Request Administrator mode for Windows Vista
; [ ] Request User mode for Windows Vista (no virtualization)
; ==============================================================
EnableExplicit
;// ------------------------------------------------------------
;// Some MACROS
;// ------------------------------------------------------------
Macro LOWORD(dwValue) : dwValue & $FFFF : EndMacro;
Macro HIWORD(dwValue) : dwValue >> 16 : EndMacro;
Macro MAKELPARAM( loWord, hiWord) : (hiWord << 16 | loWord) : EndMacro;
Macro MAKEWPARAM( loWord, hiWord) : (hiWord << 16 | loWord) : EndMacro;
;// ------------------------------------------------------------
;// Define all IDs
;// ------------------------------------------------------------
;// Define IDs for all STRINGS
#IDS_APPNAME = "My AppName"
#IDS_CLASSNAME_MAIN = "My AppName : MainWnd"
#IDS_CLASSNAME_ABOUT = "My AppName : MainAbout"
Enumeration 200
#IDC_ABOUT_OK
EndEnumeration
; // ------------------------------------------------------------
; // GLOBAL stuff...
; // ------------------------------------------------------------
Global hInstance = GetModuleHandle_(0)
Global g_DefaultFont = GetStockObject_(#DEFAULT_GUI_FONT);
Global result
;// Windows
Global g_hWnd_Main
Global g_hWnd_About
;// Controls
Global g_hAbout_BtnOK
;// ------------------------------------------------------------
;// Define all functions
;// ------------------------------------------------------------
Declare WindowCallback_Main ( hWnd, message, wParam, lParam);
Declare WindowCallback_About ( hWnd, message, wParam, lParam);
Declare Main_OnClose( hWnd, message, wParam, lParam)
;/******************************************************************
;* *
;* Entry WINAPI Main *
;* *
;******************************************************************/
Procedure WINAPI_WinMain( hInstance, hPrevInstance, lpCmdLine , nCmdShow )
Static szClassName_Main.s = #IDS_CLASSNAME_MAIN
Static szClassName_About.s = #IDS_CLASSNAME_ABOUT
Static wClass1.WNDCLASSEX;
Static wClass2.WNDCLASSEX
Static msg.MSG;
;// Check if an instance is already running
; If CreateMutex_( 0, 1, #IDS_APPNAME) = 0 Or GetLastError_() <> 0
; MessageBox_(0, #IDS_MUTEX_INSTANCE, #IDS_APPNAME, 0)
; End
; EndIf
;// ------------------------------------------------------------
;// First: We need to declarate WNDCLASSEX we want to use
wClass1.WNDCLASSEX;
wClass2.WNDCLASSEX;
;// Clear them
ZeroMemory_(wClass1, SizeOf(WNDCLASSEX));
ZeroMemory_(wClass2, SizeOf(WNDCLASSEX));
;// Setup them
;// first one
wClass1\cbSize = SizeOf(WNDCLASSEX);
wClass1\style = #CS_HREDRAW | #CS_VREDRAW;
wClass1\lpfnWndProc = @WindowCallback_Main();
wClass1\cbClsExtra = #Null;
wClass1\cbWndExtra = #Null;
wClass1\hInstance = hInstance;
wClass1\hIcon = #Null;
wClass1\hCursor = LoadCursor_(#Null, #IDC_ARROW);
wClass1\hbrBackground = #COLOR_WINDOW;
wClass1\lpszMenuName = #Null;
wClass1\lpszClassName = @szClassName_Main.s;
wClass1\hIconSm = #Null;
;// Second one
wClass2\cbSize = SizeOf(WNDCLASSEX);
wClass2\style = #CS_HREDRAW | #CS_VREDRAW;
wClass2\lpfnWndProc = @WindowCallback_About();
wClass2\cbClsExtra = #Null;
wClass2\cbWndExtra = #Null;
wClass2\hInstance = hInstance;
wClass2\hIcon = #Null;
wClass2\hCursor = LoadCursor_(#Null, #IDC_ARROW);
wClass2\hbrBackground = #COLOR_WINDOW;
wClass2\lpszMenuName = #Null;
wClass2\lpszClassName = @szClassName_About.s;
wClass2\hIconSm = #Null;
;//Second: register them
If (RegisterClassEx_(wClass1)) = 0
MessageBox_(#Null,
"Could not register class1",
"Window Class Failed",
#MB_ICONERROR);
EndIf
If (RegisterClassEx_(wClass2)) = 0
MessageBox_(#Null,
"Could not register class2",
"Window Class Failed",
#MB_ICONERROR);
EndIf
;//Now we can proceed with MainWnd creation
#WndMain_Style = #WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_THICKFRAME | #WS_SYSMENU | #WS_BORDER | #WS_MAXIMIZE | #WS_CLIPSIBLINGS | #WS_VISIBLE
#WndMain_StyleEx = #WS_EX_WINDOWEDGE
g_hWnd_Main = CreateWindowEx_( #WndMain_StyleEx,
szClassName_Main, #IDS_APPNAME,
#WndMain_Style,
100, 100, 800, 600,
#Null, #Null, hInstance, #Null);
;//Now we can proceed with AboutWnd creation
#WndAbout_Style = #WS_VISIBLE | #WS_POPUPWINDOW
#WndAbout_StyleEx = #WS_EX_TOPMOST
g_hWnd_About = CreateWindowEx_( #WndAbout_StyleEx,
szClassName_About, #IDS_APPNAME,
#WndAbout_Style,
100, 100, 400, 300,
g_hWnd_Main, #Null, hInstance, #Null);
;// Add shadow effect
SetClassLongPtr_(g_hWnd_About,#GCL_STYLE,$00020000)
;//Check if both windows are created
If(g_hWnd_Main) = 0
MessageBox_(#Null,"Could not create window1","Window Creation Failed",#MB_ICONERROR);
EndIf
If(g_hWnd_About) = 0
MessageBox_(#Null,"Could not create window2","Window Creation Failed",#MB_ICONERROR);
EndIf
;//Now we can show some windows
ShowWindow_( g_hWnd_Main, #SW_MAXIMIZE );
UpdateWindow_( g_hWnd_Main);
ShowWindow_( g_hWnd_About, #SW_SHOW );
UpdateWindow_( g_hWnd_About);
;//Last Step: handle message
msg.MSG;
ZeroMemory_(msg, SizeOf(MSG));
While(GetMessage_( msg, #Null, 0, 0))
TranslateMessage_( msg );
DispatchMessage_( msg );
Wend
UnregisterClass_( wClass1, hInstance )
UnregisterClass_( wClass2, hInstance )
ProcedureReturn msg\wParam
EndProcedure
;// ------------------------------------------------------------
;// START WINAPI_WinMain()
;// ------------------------------------------------------------
WINAPI_WinMain( GetModuleHandle_(#Null), 0, GetCommandLine_(), 0)
End
;/******************************************************************
;* *
;* The window's message handler. *
;* *
;******************************************************************/
Procedure WindowCallback_Main( hWnd, message, wParam, lParam)
Select message
Case #WM_COMMAND
Case #WM_CLOSE
Main_OnClose( hWnd, message, wParam, lParam)
;MessageBox_( hWnd, "Exit program?", "EXIT", #MB_YESNO)
;DestroyWindow_( hWnd)
Case #WM_CREATE
Case #WM_DESTROY
PostQuitMessage_(0)
;// REMOVE THIS 'CASE #WM_PAINT' AND IT WORKS, WHY?
Case #WM_PAINT
Case #WM_SIZE
Default
result = DefWindowProc_( hWnd, message, wParam, lParam)
EndSelect
ProcedureReturn result
EndProcedure
Procedure WindowCallback_About( hWnd, message, wParam, lParam)
Protected bm.BITMAP;
Protected ps.PAINTSTRUCT;
Protected hDC
Protected hDCmem
Protected hbmOld
Select message
Case #WM_CLOSE
DestroyWindow_( hWnd )
Case #WM_COMMAND
Select LOWORD(wParam)
Case #IDC_ABOUT_OK
ShowWindow_( g_hWnd_About, #SW_HIDE )
EndSelect
Case #WM_CREATE
g_hAbout_BtnOK = CreateWindowEx_(0,
"button", "OK",
#WS_CHILD | #WS_VISIBLE | #WS_BORDER,
250, 230, 100, 25,
hWnd, #IDC_ABOUT_OK, hInstance, #Null);
Case #WM_DESTROY
Case #WM_PAINT
Default
result = DefWindowProc_( hWnd, message, wParam, lParam)
EndSelect
ProcedureReturn result
EndProcedure
;/******************************************************************
;* *
;* Procedures *
;* *
;******************************************************************/
Procedure Main_OnClose( hWnd, message, wParam, lParam)
If MessageBox_( g_hWnd_Main, "Exit program?", "EXIT", #MB_YESNO) = #IDYES
DestroyWindow_( hWnd)
Else
ProcedureReturn 0
EndIf
; ProcedureReturn resultW
EndProcedure