How To Create Window with CreateWindowEx ?
Archives Forums/Win32 Discussion/How To Create Window with CreateWindowEx ?
| ||
I fail badly when i try to create a window with this api-call. here is the code: (i am sure there are lot of bugs or so, but the compiler does not complain) |
| ||
dont you need to create a WNDCLASSEX structure and call RegisterClassEx before calling the createwindow function ? |
| ||
good question! is there anybody who have basic winapi knowledge with some bm examples? |
| ||
I just checked in the msdn, it says you need to register the class before makking a call to createwindow. |
| ||
Ok, thank you very much. I will post the next error in a few minutes as i will make some errors^^. 1st problem: msdn say: he RegisterClassEx function registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function. Syntax ATOM RegisterClassEx( CONST WNDCLASSEX *lpwcx ); Parameters lpwcx [in] Pointer to a WNDCLASSEX structure. You must fill the structure with the appropriate class attributes before passing it to the function. WNDCLASSEX should look like this: typedef struct { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; } WNDCLASSEX, *PWNDCLASSEX; How to do this in BM? |
| ||
lol yeah, that is where I fell over :) I am sure someone here knows how :) |
| ||
heres a c function from my max gui module thats still in development.// The name of our window class. TCHAR szClassName[] = TEXT("MicroMax_CLASS") ; // int CLASS_GOOD; // Creates GUI Window. int MicroMax_CreateWindow(LPCTSTR szWindowText,int x,int y,int width,int height,int group,int flags){ HINSTANCE hThisInstance = GetModuleHandle(0); if(!CLASS_GOOD){ // Window class structure. WNDCLASSEX wcx ; // Now we must fill in the members of WNDCLASSEX. wcx.hInstance = hThisInstance; wcx.lpszClassName = szClassName ; wcx.lpfnWndProc = (WNDPROC)MicoMaxWinProc; wcx.style = CS_DBLCLKS; wcx.hIcon = LoadIcon (NULL, IDI_APPLICATION); wcx.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wcx.hCursor = LoadCursor (NULL, IDC_ARROW); wcx.lpszMenuName = NULL; wcx.cbSize = sizeof (WNDCLASSEX); wcx.cbClsExtra = 0; wcx.cbWndExtra = 0; wcx.hbrBackground = GetSysColorBrush(COLOR_3DFACE) ; // Register our window class with the operating system. // If there is an error, exit program. if ( !RegisterClassEx (&wcx) ) { MessageBox( 0, TEXT("Failed to register window class!"),TEXT("Error!"), MB_OK|MB_ICONERROR ) ; return 0; } // class created. CLASS_GOOD = TRUE; } // int child_window=1; if(!group){ group = (int)HWND_DESKTOP; child_window=0; }else{ child_window=1; } HWND hwnd = CreateWindowEx ( 0, szClassName, szWindowText, WS_OVERLAPPEDWINDOW|WS_VISIBLE, x, y, width, height,(HWND)group, 0, hThisInstance, 0 ); if(child_window==1){ SetParent(hwnd,(HWND)group); } if ( !IsWindow(hwnd) ) { return 0; } return (int)hwnd; } kev |
| ||
here is my feeble attempt, maybe it might help :(Global CreateWindowEx(window,Title$z,message$z, flags,x,y,w,h,Parent,guiid, hInstance,dunno); Global RegisterClassEx(wndclassex:WNDCLASSEX); Global GetModuleHandle(modname$); Const WS_OVERLAPPED = 0 Const WS_VISIBLE = $10000000 user32 = LoadLibraryA ("user32.dll") Kernel32 = LoadLibraryA ("Kernel32.dll") If user32=Null Notify("Konnte user32.dll nicht laden.") Else CreateWindowEx=GetProcAddress(user32,"CreateWindowExA") RegisterClassEx=GetProcAddress(user32,"RegisterClassExA") GetModuleHandle=GetProcAddress(Kernel32,"GetModuleHandleA") EndIf If user32=Null Notify("Konnte Kernel32.dll nicht laden.") Else GetModuleHandle=GetProcAddress(Kernel32,"GetModuleHandleA") EndIf myInstance% = GetModuleHandle(Null) Type WNDCLASSEX Field size% Field style% Field lpfnWndProc% Field extra% Field wndExtra% Field hInstance% Field hIcon% Field hCursor% Field bg% Field menuname$ Field classname$ Field hIconSm% End Type wnd:WNDCLASSEX = New WNDCLASSEX wnd.size = SizeOf(WNDCLASSEX) wnd.style = CS_HREDRAW wnd.lpfnWndProc = Null wnd.extra = DLGWINDOWEXTRA wnd.wndExtra=0 wnd.hInstance = myInstance wnd.hIcon=0 wnd.hCursor=0 wnd.bg=COLOR_WINDOW wnd.menuname=Null wnd.classname="test" wnd.hiconsm=Null If Not RegisterClassEx(wnd) Then Notify("could not register class") If Not CreateWindowEx(0,"test","test window",WS_OVERLAPPED | WS_VISIBLE,0,0,640,480,0,0,myInstance ,Null) Then Notify("could not create window") While Not KeyDown(KEY_ESCAPE) Wend |
| ||
without testing Deux example, wnd.lpfnWndProc needs to be an address of a function. some thing like this, we need the address of the winproc. Local WinProcADDR:Byte Ptr = WinProc If WinProcADDR > Null Then Print "winproc addr obtained " EndIf Function WinProc(hWnd:Int,Msg:Int,wParam:Int,lParam:Int) End Function kev |
| ||
yeah, I just rearranged code, never really tested it myself, sorry for not doing that. I have been looking at the user32.bmx code, and I think that may be helpful for regaa, the constants and functions you need are in there I think. |
| ||
here you go a working example using just blitzmax, this creates a window and waits for the close button.Import "-luser32" Extern Function GetSysColorBrush:Int(nIndex:Int) = "GetSysColorBrush@4" End Extern Const COLOR_BTNFACE = 15 Local WinProcADDR:Byte Ptr = WinProc If WinProcADDR > Null Then Print "winproc addr obtained " EndIf Local classname$ = "WindowCLASS" Local CLASSNAME_ADRR:Byte Ptr = Byte Ptr classname$ Local class:WNDCLASS = New WNDCLASS Local classADDR:Byte Ptr = Byte Ptr class class.hInstance = GetModuleHandleA(0) class.lpfnWndProc = WinProcADDR class.lpszClassName = CLASSNAME_ADRR class.hbrBackground = GetSysColorBrush(COLOR_BTNFACE) If(RegisterClassA(classADDR) <> Null) Then Print "class reg ok" EndIf Local message:MSG = New MSG Local messageADDR:Byte Ptr = Byte Ptr message Local windowTitle$ = "Testing" Local windowTitleADDR:Byte Ptr = Byte Ptr windowTitle$ Const WS_CAPTION = $C00000 Const WS_SYSMENU = $80000 Const WS_VISIBLE = $10000000 Const WS_MINIMIZEBOX = $20000 Const WS_MAXIMIZEBOX = $10000 Const WM_DESTROY = 2 Local lpParamADDR:Byte Ptr Local window = CreateWindowExA( 0,CLASSNAME_ADRR,windowTitleADDR,WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_VISIBLE,100,100,200,200,0,0,GetModuleHandleA(0),lpParamADDR ) While Not KeyDown(KEY_ESCAPE) GetMessageA(messageADDR,0,0,0) TranslateMessage(messageADDR) DispatchMessageA(messageADDR) Wend ' ' ' Function WinProc(hWnd:Int,Msg:Int,wParam:Int,lParam:Int) Select Msg Case WM_DESTROY Notify "Bye!" End End Select Return DefWindowProcA(hWnd,Msg,wParam,lParam) End Function needs cleaning up. kev. |
| ||
many thanks to that much examples. i will check'em out. god job dudes :P |
| ||
Very cool kev. Thanks! |
| ||
I tryed to extend some parts, but whenever i use SendMessage (declared in user32.bmx) i get this error: undefined reference to `SendMessage@16 :( |
| ||
regaa im not sure why you get the error, but this will work. add the sendmessage to the extern ... end extern Function SendMessage:Int(hWnd:Int,MSG:Int,wParam:Int,lParam:Int) = "SendMessageA@16" then to test use SendMessage window,WM_DESTROY,0,0 after creating the window. kev |
| ||
Thank you very much. I've learned some important BM basics :p . |
| ||
wow very cool, awsome kev ! Thanks |
| ||
Here's one with some buttons and a keypress - you can press [ESC] to quit. |
| ||
just to make a note, under WM_COMMAND the HIWORD(wParam) specifies the notification code if the message is from a control, this will be 0 if the message is from a menu, the ID of the menu is found in the LOWORD(wParam) heres 2 functions to get the low and hi words. Function LOWORD(value) Return value And $FFFF End Function Function HIWORD(value) Return (value Shr 16) End Function kev |
| ||
I'm trying to add a font, but my CreateFont call makes Blitz quit: |
| ||
I can add a font to ONE control using this code, adding the font to more than one control makes Blitz quit: |
| ||
this is how i do it in winblitz3d. you shold be able to convert this easy.Function OpenFont(fontname$,width=12,height=8,bold=0,italic=0,underline=0) font = apiCreateFont(width,height,0,0,bold,underline,0,0,0,0,0,0,0,GRAB_StringAddr(fontname$)) Return font End Function Function Usefont(gadget,font) hdc = apiGetWindowDC(gadget) hfontprev = apiSelectObject(hdc,font) apiSendMessage gadget,WM_SETFONT,apiSelectObject(hdc,font),1 End Function kev |
| ||
Thanks, kev. I see I've been doing it all wrong, I'll make those SelectObject() changes and try again. |
| ||
I'm still having troubles: http://www.blitzbasic.com/Community/posts.php?topic=50237 :) |
| ||
btw : LOWORD needs to be changed to: ("&" not "AND" )Function LOWORD(value) Return value & $FFFF End Function |
| ||
Hi, I'm late... Can anyone make this code by Kev work with the latest version of BlitzMax : Import "-luser32" Extern Function GetSysColorBrush:Int(nIndex:Int) = "GetSysColorBrush@4" End Extern Const COLOR_BTNFACE = 15 Local WinProcADDR:Byte Ptr = WinProc If WinProcADDR > Null Then Print "winproc addr obtained " EndIf Local classname$ = "WindowCLASS" Local CLASSNAME_ADRR:Byte Ptr = Byte Ptr classname$ Local class:WNDCLASS = New WNDCLASS Local classADDR:Byte Ptr = Byte Ptr class class.hInstance = GetModuleHandleA(0) class.lpfnWndProc = WinProcADDR class.lpszClassName = CLASSNAME_ADRR class.hbrBackground = GetSysColorBrush(COLOR_BTNFACE) If(RegisterClassA(classADDR) <> Null) Then Print "class reg ok" EndIf Local message:MSG = New MSG Local messageADDR:Byte Ptr = Byte Ptr message Local windowTitle$ = "Testing" Local windowTitleADDR:Byte Ptr = Byte Ptr windowTitle$ Const WS_CAPTION = $C00000 Const WS_SYSMENU = $80000 Const WS_VISIBLE = $10000000 Const WS_MINIMIZEBOX = $20000 Const WS_MAXIMIZEBOX = $10000 Const WM_DESTROY = 2 Local lpParamADDR:Byte Ptr Local window = CreateWindowExA( 0,CLASSNAME_ADRR,windowTitleADDR,WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_VISIBLE,100,100,200,200,0,0,GetModuleHandleA(0),lpParamADDR ) While Not KeyDown(KEY_ESCAPE) GetMessageA(messageADDR,0,0,0) TranslateMessage(messageADDR) DispatchMessageA(messageADDR) Wend ' ' ' Function WinProc(hWnd:Int,Msg:Int,wParam:Int,lParam:Int) Select Msg Case WM_DESTROY Notify "Bye!" End End Select Return DefWindowProcA(hWnd,Msg,wParam,lParam) End Function This would be great :) |
| ||
Just to clarify ;) you all know that these functions are already shipped with Blitzmax? If not, then take a look to the pub.win32 module. this module already gives you everything you need (structs and functions) for these things. |
| ||
Thanks, I'll take a look :) |
| ||
hm, there is an Problem with the MaximizeStrict Framework PUB.Win32 Import BRL.System Import BRL.EventQueue Import BRL.basic Extern "Win32" Function UpdateWindow(hWnd) End Extern Global CLASS_NAME:Byte Ptr="bbW32 Window".ToCString() ' Wie heißt unsere Anwendung Global hinst=GetModuleHandleA(0) ' was ist uinsere instance Local hwnd%=CreateHWND(600,400,0,"Jan_'s Win32 Application".ToCString()) ' Fenster erstellen 'showwindow(hwnd,sw_show) ' fenster Zeigen 'showwindow(hwnd,sw_hide) ' fenster verstecken Local ende% Repeat WaitEvent() ' warten, das was passiert, das wichtig ist --> 0% CPU last ende=True Until (ende=True) DestroyWindow(hWnd) ' das Fenster wieder löschen End Function WndProc( hwnd,message,wp,lp ) "win32" Local event:TEvent Select message ' hier reagieren wir auf die aktionen die der nutzer auslöst Case WM_CLOSE ' schließen event=New TEvent PostEvent(event) ' so, das sendet an Waitevent das es was machen soll (siehe oben) postquitmessage(0) DestroyWindow(hWnd) End Return Case WM_DESTROY ' zerstören event=New TEvent PostEvent(event) ' so, das sendet an Waitevent das es was machen soll (siehe oben) postquitmessage(0) DestroyWindow(hWnd) End Return Case WM_MOVE ' bewegen 'updatewindow(hwnd) Return Case WM_SIZE 'bbSystemEmitOSEvent hwnd,message,wp,lp,Null 'updatewindow(hwnd) Return Case WM_Paint updatewindow(hwnd) Return ' Case WM_MOUSEMOVE 'Default 'bbSystemEmitOSEvent hwnd,message,wp,lp,Null End Select Return DefWindowProcA( hwnd,message,wp,lp ) End Function Function CreateHWND(width,height,fullscreen,WINDOW_TITLE:Byte Ptr,PosX%=100,PosY%=100) ' Fenster erstellen Local style,ex_style,hwnd Local hinst=GetModuleHandleA(0) Global wndClas If Not wndClas Local wc:WNDCLASS=New WNDCLASS Local hinst=GetModuleHandleA(0) 'Local icon:Byte Ptr="IDI_INFORMATION".ToCString() wc.style=CS_HREDRAW Or CS_VREDRAW ' Fensterstyle wc.lpfnWndProc=WndProc 'Zeiger auf die Fensterprozedur wc.cbClsExtra=0 wc.cbWndExtra=0 wc.hInstance=hinst ' Instanz des Programms wc.hIcon=LoadIconA(Null, Null) 'Handle eines Icons das z.B. mit LoadIcon() geladen wurde wc.hbrBackground = GetStockObject (LTGRAY_BRUSH) wc.hCursor=LoadCursorA( Null,Byte Ptr IDC_ARROW ) 'Handle eines Cursors wc.lpszClassName=CLASS_NAME ' Name der zu registrierenden Fensterklasse wndClas=RegisterClassA( wc ) If Not wndClas Throw "Failed to register window class" EndIf EndIf ex_style=WS_EX_TRANSPARENT style=WS_VISIBLE|WS_SYSMENU|WS_CAPTION|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX'|WS_SYSMENU Local rect[]=[posx,posy,width+posx,height+posy] hWnd=CreateWindowExA(.. ex_style,.. CLASS_NAME,.. WINDOW_TITLE,.. style,.. posx,posy,width,height,.. 0,0,hinst,Null) ShowWindow(hWnd,SW_SHOW); MemFree WINDOW_TITLE If Not hwnd Throw "Failed to create window" Return hwnd End Function |