Dialog Window Style!
BlitzMax Forums/BlitzMax Module Tweaks/Dialog Window Style!
| ||
Ever notice how most programs use option windows and dialogs that don't have any icon on the left side of the titlebar? Now you too can have professional-looking application windows or custom requesters, with my amazing WINDOW_DIALOG tweak! Here's how: First, open "mod\brl\maxgui.mod\gadget.bmx" and add this constant at line 60, then save the file: Const WINDOW_DIALOG=512 Now open "mod\brl\win32maxgui.mod\win32gui\win32window.cpp". Find this section that starts at line 24: //1=title if( style&1 ){ wstyle|=WS_CAPTION|WS_SYSMENU; if( style&2 ) wstyle|=WS_MINIMIZEBOX|WS_MAXIMIZEBOX; }else{ wstyle|=WS_POPUP; } And change it to this: //1=title if( style&1 ){ wstyle|=WS_CAPTION|WS_SYSMENU; if( style&2 ) wstyle|=WS_MINIMIZEBOX|WS_MAXIMIZEBOX; if( style&512 ) xstyle|=WS_EX_DLGMODALFRAME; }else{ wstyle|=WS_POPUP; } Finally, open "mod\brl\win32maxgui.mod\win32gui\win32hwnd.cpp" and comment out line 184: // if (!icon) icon=LoadIcon( NULL,IDI_APPLICATION ); Recompile mods brl.maxgui and brl.win32maxgui. Then run this code in BlitzMax: Strict Local w=400 Local h=300 Local win:TGadget=CreateWindow("Dialog Window",(Desktop().ClientWidth()-w)/2,(Desktop().ClientHeight()-h)/2,w,h,Null,WINDOW_TITLEBAR+WINDOW_DIALOG) While WaitEvent()<>EVENT_WINDOWCLOSE Wend |
| ||
Part II I noticed that using an icon in my main program window overides my icon-less window. To overcome this, you have to create a new window class. This can be done easily by just copying existing code. Open "mod\brl\win32maxgui.mod\win32gui\win32hwnd.cpp" and find the Win32Hwnd::className() method. Copy the entire method and paste it again, then change the name to Win32Hwnd::classNameDialog(). Comment out the line where the icon is loaded, and the line where _wc.hicon is set. Also, change the class name to "BLITZMAX_DIALOG_CLASS". It should look like this: const char *Win32Hwnd::classNameDialog(){ static int done; static WNDCLASS _wc; static const char *name="BLITZMAX_DIALOG_CLASS"; if( done ) return name; // HICON icon=LoadIcon(GetModuleHandle(0),(const char*)101); // if (!icon) icon=LoadIcon( NULL,IDI_APPLICATION ); if( !_wc.lpfnWndProc ){ _wc.style=CS_OWNDC|CS_HREDRAW|CS_VREDRAW; _wc.lpfnWndProc=classWndProc; _wc.hInstance=GetModuleHandle(0); //_wc.hIcon=icon; _wc.hCursor=LoadCursor( 0,MAKEINTRESOURCE( (DWORD)IDC_ARROW ) ); _wc.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1); _wc.lpszMenuName=0; _wc.lpszClassName=name; _wc.cbWndExtra=DLGWINDOWEXTRA; RegisterClass(&_wc); } SetWindowsHookEx( WH_GETMESSAGE,GetMessageProc,GetModuleHandle(0),GetCurrentThreadId() ); SetWindowsHookEx( WH_KEYBOARD,KeyboardProc,GetModuleHandle(0),GetCurrentThreadId() ); done=1; atexit(freehooks); return name; } Now open "mod\brl\win32maxgui.mod\win32gui\win32hwnd.h" and add a new function declaration at line 66: static const char *className(); static const char *classNameDialog(); Finally, open "mod\brl\win32maxgui.mod\win32gui\win32window.cpp". Find this line: HWND hwnd=CreateWindowEx( xstyle,Win32Hwnd::className(),0,wstyle,0,0,0,0,parent,hmenu,GetModuleHandle(0),0 ); And replace it with this: HWND hwnd; if ( xstyle&WS_EX_DLGMODALFRAME ) { hwnd=CreateWindowEx( xstyle,Win32Hwnd::classNameDialog(),0,wstyle,0,0,0,0,parent,hmenu,GetModuleHandle(0),0 ); }else{ hwnd=CreateWindowEx( xstyle,Win32Hwnd::className(),0,wstyle,0,0,0,0,parent,hmenu,GetModuleHandle(0),0 ); } That's it! Recompile brl.win32maxgui and you can use icons in windows, and icon-less dialog windows. |
| ||
I just synced mods and followed my own instructions above. If you do exactly what it says, it will work with the latest MaxGUI 1.15. Why not add this to the official module? I don't know if there is an equivalent in Mac and Linux, but it is an optional windows flag anyways, so I think that is acceptable. |
| ||
sorry, but this was discussed many times before. Only things which will work on all 3 plattforms and are prooved to be usefull will make it to the offical modules. Believe me I have suggest some things and everytime it was the same explaination. But your code is very usefull and I have already add it to my MaxGui. Thx. |
| ||
With MaxGUI.win32maxguiex it is much easier to set this up, and it compiles about 20 times faster, since it is all BlitzMax code! Open "win32maxguiex.bmx". 1. Add this function inside the TWindowsGUIDriver type. I am going to assume ClassAtom2 is a spare window class, because I could not find it being used anywhere: Function DialogClassName$() Global _name$ Global _wc:WNDCLASSW 'Global _icon If Not _name _name="BLITZMAX_DIALOG_CLASS" '_icon=LoadIconW(GetModuleHandleW(Null),Short Ptr(101)) _wc=New WNDCLASSW _wc.style=CS_OWNDC|CS_HREDRAW|CS_VREDRAW _wc.lpfnWndProc=ClassWndProc _wc.hInstance=GetModuleHandleW(Null) '_wc.hIcon=_icon _wc.hCursor=LoadCursorW( 0,Short Ptr( IDC_ARROW ) ) _wc.hbrBackground=COLOR_BTNSHADOW _wc.lpszMenuName=Null _wc.lpszClassName=_name.ToWString() _wc.cbWndExtra=DLGWINDOWEXTRA ClassAtom2=RegisterClassW(_wc) EndIf Return _name EndFunction 2. Replace the TWindowsWindow Create() method with this code: Method Create:TWindowsWindow(group:TGadget,style) Local hwnd,parent,client _style=style '_xstyle=|WS_EX_CONTROLPARENT _wstyle=WS_CLIPSIBLINGS|WS_VISIBLE|WS_CLIPCHILDREN If group Then parent = group.Query(QUERY_HWND) If style&WINDOW_TITLEBAR _wstyle:|WS_OVERLAPPED|WS_SYSMENU If style&WINDOW_RESIZABLE _wstyle:|WS_MINIMIZEBOX|WS_MAXIMIZEBOX '========================================================= '========================================================= 'Added this: If style&WINDOW_DIALOG _xstyle:|WS_EX_DLGMODALFRAME '========================================================= '========================================================= Else _wstyle:|WS_POPUP EndIf If style&WINDOW_RESIZABLE _wstyle:|WS_SIZEBOX EndIf If style&WINDOW_MENU _hmenu=CreateMenu_() AppendMenuW( _hmenu,MF_STRING,Null,_wstrEmpty ) EndIf If style&WINDOW_TOOL _xstyle:|WS_EX_TOOLWINDOW EndIf If style&WINDOW_HIDDEN _wstyle:&~WS_VISIBLE End If '========================================================= '========================================================= 'Commented out -> hwnd=CreateWindowExW(_xstyle,TWindowsGUIDriver.ClassName(),"",_wstyle,0,0,0,0,parent,_hmenu,GetModuleHandleW(Null),Null) 'Replaced with this: If (WS_EX_DLGMODALFRAME & _xstyle) hwnd=CreateWindowExW(_xstyle,TWindowsGUIDriver.DialogClassName(),"",_wstyle,0,0,0,0,parent,_hmenu,GetModuleHandleW(Null),Null) Else hwnd=CreateWindowExW(_xstyle,TWindowsGUIDriver.ClassName(),"",_wstyle,0,0,0,0,parent,_hmenu,GetModuleHandleW(Null),Null) EndIf '========================================================= '========================================================= If style&WINDOW_STATUS _status=CreateWindowExW(0,"msctls_statusbar32","",WS_CHILD|WS_VISIBLE,0,0,0,0,hwnd,0,GetModuleHandleW(Null),Null) client=CreateWindowExW(0,TWindowsGUIDriver.ClassName(),"",WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,0,0,hwnd,0,GetModuleHandleW(Null),Null) SetWindowPos( _status, HWND_TOPMOST,0,0,0,0,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOSIZE) EndIf Register GADGET_WINDOW,hwnd,client,False If style&WINDOW_ACCEPTFILES DragAcceptFiles _hwnd,True EndIf Return Self EndMethod 3. Declare the constant WINDOW_DIALOG=512 somewhere in MaxGUI.MaxGUI or MaxGUI.Win32MaxGUIEx. 4. Recompile MaxGUI.Win32MaxGUIEx and MaxGUI.MaxGUI, if you added the constant in this module. |
| ||
Hi Leadwerks, Got back a day or so ago, so I've had time to look into this for. I don't think that either Linux or Mac OS X have miniature window icons anyway and so a WINDOW_DIALOG flag would be somewhat obsolete if removing the icon was the only difference. How about if we simply got MaxGUI to make all child windows (i.e. windows with a parent specified) iconless on Windows. All dialog boxes tend to be parented to a main window. I think that would certainly be more keeping with the apparent Windows GUI design guidelines. Another approach, would be to think more in depth about about how a MaxGUI dialog window should be implemented on each platform. For example, on OS X dialog are usually presented in the form of a sheet. These tend to be used for dialog boxes parented to a main window. Standard dialog boxes are pretty much normal windows. Also, should a WINDOW_DIALOG window be sticky (i.e. always-on-top) for, similar to WINDOW_TOOL? Finally, should it be modal, and if so how do we handle such modal behaviour using the current MaxGUI framework. The FLTK framework is pretty basic, so a WINDOW_DIALOG window will probably have no effect on Linux. Anyone any thoughts on any of the ideas above? |
| ||
I think making child windows icon-less is the best solution. |
| ||
OK, please checkout the latest MaxGUI changes (rev. 83), build modules and let me know how you get on. Anyone else have any strong views about this new behaviour? |
| ||
I liked it, it made MaxIDE-CE look better at least =) |
| ||
It works great. |
| ||
This is great! Thanks, Seb. |
| ||
Fantastic! I've just committed the tweak to the older MaxGUI.Win32MaxGUI module too, just in case anyone out there is still using it. |
| ||
Excellent! |