What parameters does PB use internally to create windows?

Just starting out? Need help? Post your questions and find answers here.
halo
Enthusiast
Enthusiast
Posts: 104
Joined: Mon Jan 26, 2004 2:49 am

What parameters does PB use internally to create windows?

Post by halo »

I am attempting to create a window with no titlebar icon in BlitzMax, like this. This is a window, not an actual messagebox dialog:
Image

Apparently it can be done in PureBasic with the following code:

Code: Select all

OpenWindow(0, 0, 0, 240, 100, "Modal frame", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered | #PB_Window_Invisible)
SetWindowLong_(WindowID(0), #GWL_EXSTYLE, GetWindowLong_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_DLGMODALFRAME)
HideWindow(0, 0)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
However, it doesn't work in BlitzMax:

Code: Select all

Extern "win32"
	Function SetWindowLong:Int(hwnd:Int,index:Int,value:Int)="SetWindowLongA@12"
	Function GetWindowLong:Int(hWnd:Int, index:Int)="GetWindowLongA@8"
EndExtern

Local w=400
Local h=300
Local win:TGadget=CreateWindow("Window",(Desktop().ClientWidth()-w)/2,(Desktop().ClientHeight()-h)/2,w,h,Null,WINDOW_HIDDEN+WINDOW_TITLEBAR)
Local hWnd:Int = QueryGadget(win,QUERY_HWND)

SetWindowLong hWnd,GWL_EXSTYLE,GetWindowLong(hwnd,GWL_EXSTYLE)+WS_EX_DLGMODALFRAME
SetWindowPos( hWnd, 0,0,0,0,0, SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER )
ShowGadget win

While WaitEvent()<>EVENT_WINDOWCLOSE
Wend
The only difference I can think of is perhaps BlitzMax and PureBasic use different parameters when the window is initially created, which makes PureBasic windows modifiable into the desired style, while BlitzMax windows are not.

My question is what are the parameters PureBasic uses internally when creating a window with the API command CreateWindow() or CreateWindowEx()? Is there anything else that might make BlitzMax windows not work with this style, while PureBasic windows do?
IndieP

Post by IndieP »

What about using the Pop-up style?
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

I don't really understand: Is it possible to create "Don't ask me this again"-windows with 1 command? Like MessageRequester() creates 1 whole window + buttons? :shock:

Please, can you give some more code?

Your first code just creates an empty window in my PB 4.01... :cry:
PB 4.30

Code: Select all

onErrorGoto(?Fred)
halo
Enthusiast
Enthusiast
Posts: 104
Joined: Mon Jan 26, 2004 2:49 am

Post by halo »

The point is to make a window with a full-size titlebar, "X" close button, but no icon on the top-left. This can be used for a custom messagebox, an options window, or whatever else you want. As demonstrated, it works perfectly in PureBasic, and I am trying to figure out why it doesn't work in BlitzMax.
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: What parameters does PB use internally to create windows

Post by ricardo »

halo wrote: However, it doesn't work in BlitzMax
Why don't ask on blitzmax forum? Sounds more logic to me.
halo
Enthusiast
Enthusiast
Posts: 104
Joined: Mon Jan 26, 2004 2:49 am

Post by halo »

Why don't ask on blitzmax forum? Sounds more logic to me.
I am, but they don't have any idea why it doesn't work. I am guessing that PB windows have an owner-drawn caption, or have some setting they are created with that allows what I want, because it obviously isn't just a matter of window style settings.

I am trying to figure out what is it that PureBasic does that allows this appearance.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I'd look more closely at your blitz code as the following api code works fine, i.e. no internal Purebasic windows commands are used.

Code: Select all

Procedure WindowCallback(Window, Message, wParam, lParam) 
  Select Message 
    Case #WM_CLOSE 
      If MessageBox_(Window, "You sure?", "EXIT", #MB_YESNO) = #IDYES 
        DestroyWindow_(Window) 
      Else 
        Result  = 0 
      EndIf 
    Case #WM_DESTROY 
      PostQuitMessage_(0) 
      Result  = 0 
    Default 
      Result  = DefWindowProc_(Window, Message, wParam, lParam) 
  EndSelect 
  ProcedureReturn Result 
EndProcedure 

#Style  = #WS_VISIBLE | #WS_SYSMENU 

WindowClass.s  = "myclass" 
wc.WNDCLASSEX 
wc\cbSize  = SizeOf(WNDCLASSEX) 
wc\lpfnWndProc  = @WindowCallback() 
wc\hCursor  = LoadCursor_(0, #IDC_ARROW) 
wc\hbrBackground  = #COLOR_WINDOW+1 
wc\lpszClassName  = @WindowClass 
RegisterClassEx_(@wc) 

hWndMain  = CreateWindowEx_(#WS_EX_DLGMODALFRAME	, WindowClass, "Test-Window", #Style, 10, 10, 200, 200, 0, 0, 0, 0) 

While GetMessage_(msg.MSG, #Null, 0, 0 ) 
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
Wend 
I may look like a mule, but I'm not a complete ass.
halo
Enthusiast
Enthusiast
Posts: 104
Joined: Mon Jan 26, 2004 2:49 am

Post by halo »

Thank you! That was what I needed. I traced the BlitzMax window class back and found that it was actively loading the default exe icon. I commented that out and the setting took effect.

I searched for the answer to this for a long time. The PB forum is one of the best places to find people who know the Windows API. :D
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

You're welcome.
I may look like a mule, but I'm not a complete ass.
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

I don't know, if this belongs to the topic, but nevertheless, I'll ask you.

How can I create a MessageBox containing a checkbox "Don't show this again"? Like the image in the 1st post!

When I browsed the internet with Google, I just found a download-packet (many *.mainfest, *.c, *.h files...) which should make me able to create those Messageboxes. I mention the keyword "XMessageBox".

Please, can you help me? I don't want to create those windows on my own. :?
PB 4.30

Code: Select all

onErrorGoto(?Fred)
halo
Enthusiast
Enthusiast
Posts: 104
Joined: Mon Jan 26, 2004 2:49 am

Post by halo »

Well, this looks like they have done all the work for you already:
http://www.codeproject.com/dialog/xmessagebox.asp

Alternatively, it might be easier just to create a messagebox from a window, using the style I just showed you.
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

I already found this link via Google.

Morover, I don't understand your 2nd sentence:: Which 'messagebox from a window' did you show my?

I compiled all your codes from this thread, but nothing happended... 1 of the code even just created a window with no content.

I have PB 4.01.
PB 4.30

Code: Select all

onErrorGoto(?Fred)
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

I'll give it a go. Optimize, cleanup, and use as desired. :)

updated for PB6+ by Fred

Code: Select all

; ***************************************************** 
; Code    : MessageRequester with "Don't ask me again" 
; Author  : Sparkie 
; Date    : November 17, 2006 
; OS      : Windows only 
; License : It's all yours to use as you so desire 
;           (props/credit are welcome) 
; ***************************************************** 

Global hHook = 0, oldProc = 0, askagain = 0 

;...This one is still missing in PB def 
#BS_TEXT = 0 

;...Make sure Checkbox ID <> any of the other MessageRequester buttons 
#CheckBoxID = 12 

;...Subclassed MessageRequester Procedure() 
Procedure MsgBoxProc(hwnd, msg, wParam, lParam) 
  result = CallWindowProc_(oldProc, hwnd, msg, wParam, lParam) 
  Select msg 
    Case #WM_DESTROY 
      ;...Get handle to our checkbox 
      hCheckBox = GetDlgItem_(hwnd, #CheckBoxID) 
      ;...Get the checkbox state. <0 = not checked> <1 = checked> 
      ;...For this test I'll set a Global var to = CheckBox state 
      ;...In a real app you could set the value in a config/ini file 
      ;...or maybe a use a Registry setting 
      askagain = SendMessage_(hCheckBox, #BM_GETCHECK, 0, 0) 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

;...Our hook Procedure() 
Procedure CBTProc(nCode, wParam, lParam) 
  result = CallNextHookEx_(hHook, nCode,wParam,lParam) 
  ;...Creation of MessageRequester is here 
  If nCode = #HCBT_CREATEWND 
    *cbt_cw.CBT_CREATEWND = lParam 
    *lpcs.CREATESTRUCT = *cbt_cw\lpcs 
    ;...Take action only if this is our MessageRequester 
    If *lpcs\hWndParent = WindowID(0) And *lpcs\lpszClass = 32770 
      ;...Resize the MessageRequester to make room for our CheckBoxGadget 
      *lpcs\cy + 30 
    EndIf 
    result = 0 
  EndIf 
  
  ;...MessageRequester is about to become active 
  ;...Here we will add our "Don't ask me this again" checkbox 
  If nCode = #HCBT_ACTIVATE 
    hMsgBox = wParam 
    
    ;...Subclass the MessageRequester 
    oldProc = SetWindowLong_(hMsgBox, #GWL_WNDPROC, @MsgBoxProc()) 
    hCheckBox = CreateWindowEx_(0, "Button", "Don't ask me this again.", #BS_AUTOCHECKBOX | #BS_TEXT | #WS_GROUP | #WS_TABSTOP | #WS_CHILD | #WS_VISIBLE, 10, 95, 150, 25, hMsgBox, #CheckBoxID, GetModuleHandle_(0), 0) 
    hFont = GetStockObject_(#DEFAULT_GUI_FONT) 
    SendMessage_(hCheckBox, #WM_SETFONT, hFont, 0) 
    ;...Release the hook 
    If hHook 
      UnhookWindowsHookEx_(hHook) 
      hHook = 0 
    EndIf 
    result = 0 
  EndIf 
  ProcedureReturn result 
EndProcedure 
If OpenWindow(0, 100, 100, 300, 200, "Don't ask me again", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  ButtonGadget(1, 10, 40, 280, 22, "Display Custom MessageRequester") 
  TextGadget(2, 10, 80, 280, 25, "") 
  Repeat 
    Event = WaitWindowEvent() 
    If Event = #PB_Event_Gadget And EventGadget() = 1 
      ;...Create a local hook to watch for MessageRequester 
      If askagain = 0 
        hHook = SetWindowsHookEx_(#WH_CBT, @CBTProc(), 0, GetCurrentThreadId_()) 
        MessageRequester("Welcome", "Do you want to continue?", #MB_YESNO | #MB_ICONQUESTION) 
      Else 
        MessageRequester("Sorry", "You requested not to see that message again.", #MB_OK | #MB_ICONINFORMATION) 
      EndIf 
      Select askagain 
        Case 0 
          SetGadgetText(2, "Ask me again was not checked") 
        Case 1 
          SetGadgetText(2, "Ask me again was checked") 
      EndSelect 
    EndIf 
  Until Event = #PB_Event_CloseWindow 
EndIf 
;...Just in case it's still there 
If hHook 
  UnhookWindowsHookEx_(hHook) 
  hHook = 0 
EndIf 
End
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Fabulous piece of code, Sparkie, and very instructive. You really are a coding guru, thanks for posting!
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

Thank you! I will have a closer look later. :D

WindowHook? Does this take effect on all MessageBoxes I open? I aask, because in my program I want some MessageBoxes with checkbox and some without checkboxes.
PB 4.30

Code: Select all

onErrorGoto(?Fred)
Post Reply