ManagedMessageBox 2.0

Developed or developing a new product in PureBasic? Tell the world about it.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

ManagedMessageBox 2.0

Post by netmaestro »

This library is now available in version 2.0 as a .pbi include. Features are:

- optional timed messagebox
- optional screenposition
- optional background color
- optional background image
- optional banner image
- optional silent operation (for non-icon messageboxes only)
- optional increased modal level

Strings are not used to find the button ID's, so languages other than english should not present a problem.

Any bugs or problems, please post and they will be fixed promptly.

May 25, 2008: More extensive testing revealed several bugs which are now fixed. If you got the original, please copy this version over it. Note that the command takes one more parameter now for the mmb_data variable as not passing it created problems with subsequent calls to the function. Also, doing it this way makes the code compatible with Tailbite so if you want to compile it into a userlib it will work fine. I tried it with the latest Tailbite and experienced no problems.

May 26, 2008: Fixed an issue where a timed message box sometimes wouldn't auto-close if the mouse was being moved over it.

May 28, 2008: Fixed a small leak where the textgadget used for the remaining seconds wasn't being freed. Also removed some unused lines of code left over from an earlier development stage that are no longer necessary.

June 2, 2008:

- Fixed a bug where the background brushes for the static controls wouldn't show correctly if XP themes were enabled and an image was used for the messagebox background.

- Fixed a bug where a programmer who had an unrelated image initialized with a static #image of 0 could have had his image inadvertently freed by the library.

- Added: Banner image option. If you make a logo image and pass it to the library it will be used as a banner for the messagebox. Here's an example:

I made this test logo:
Image

and this test background:
Image

Now this code:

Code: Select all

IncludeFile "ManagedMessageBox20.pbi"

UsePNGImageDecoder()
LoadImage(1, "testlogo.png")

LoadImage(2, "testbackground.png")

With mmb_data.MMBDATA
  \BkContent = 2
  \BkContentType = #MMB_IMAGE
  \bannerImage = 1
  \defaultButton = 3
  \delayTime = 30
  \modalLevel = 1
EndWith

ManagedMessageBox("Announcement:", "Holy insect bites, Batman! It's the Green Hornet! Run for your life!", mmb_data, #MB_ABORTRETRYIGNORE | #MB_ICONINFORMATION)
makes this messagebox:
Image

The logo is extended on either side without stretching.

June 6, 2008: Fixed a bug in the Banner drawing where the left brush was also being used on the right side. Would affect banners with a horizontal gradient.

Code: Select all

;================================================================= 
; Library:           ManagedMessageBox 2.0 
; Author:            Lloyd Gallant (netmaestro) 
; Date:              January 9, 2008 
; Target OS:         Microsoft Windows All 
; Target Compiler:   PureBasic 4.0 and later 
; License:           Free, unrestricted, no warranty 
; 
; Last Update:       June 6, 2008 
; 
; Usage: Filling the MMMBDATA structure 
; 
; Use only the programmer-selectable options. All fields are optional. 
; If you do not fill x and y for a screenposition, the messagebox will 
; be screencentered. 
; 
; #MMB_ Constant usage: 
; 
;   If you do not fill bkContentType (or use #MMB_NOBACKGROUND) no special 
;   background options will be applied. 
; 
;   To have a background color, fill bkContent with a colorref and fill 
;   bkContentType with #MMB_COLOR 
; 
;   To have a background image, fill bkContent with the #image you want to use 
;   and fill bkContentType with #MMB_IMAGE. 
; 
;   To have a logo banner, fill bannerImage with the #image you want for a banner 
; 
;   #MMB_TEST is a special case. If you have a text in mind for the messagebox 
;   and you would like to have a background image, it is useful to know what 
;   size the client area of the message box will be. If you fill bkContentType 
;   with #MMB_TEST, the caption of the message box will be ignored and it will 
;   show the width And height. You'd only do this during development so you can 
;   easily create a nice image the right size for the message box. 
; 
; txtColor: Put a colorref here if a text color other than black is desired. 
; 
; delayTime: Leave at 0 for a non-timed message box or put a number of seconds 
; to wait before the default button is auto-selected. 
; 
; defaultButton: choose from a 1-based enumeration of the buttons on your 
; messagebox. For example, if your flags are #MB_ABORTRETRYIGNORE, you will 
; have three buttons. Filling defaultButton with 2 will make RETRY the default 
; choice. 
; 
; modalLevel: For normal application modality, leave at 0. For system-level 
; modality (the box will never allow itself to be minimized), fill with 1. 
; 
; silent: Not for use in icon message boxes (like #MB_ICONERROR, etc.), this 
; flag will remove the "ding" sound made when the message box appears. Fill with 
; 0 for normal sound or 1 to suppress the ding. 
; 
; You should compile ThreadSafe if using this library. 
; 
; Enjoy it! 
; 
;================================================================= 

#MMB_NOBACKGROUND = 0 
#MMB_COLOR        = 2 
#MMB_IMAGE        = 4 
#MMB_BANNER       = 8 
#MMB_TEST         = 16 

Structure MMBDATA 
  ;------------------------------------------------- 
  ;    Programmer-Selectable Options 
  ;------------------------------------------------- 
  x.l               ; In, desired x position on screen 
  y.l               ; In, desired y position on screen 
  bkContent.l       ; In, long value representing imageid or colorref depending on type 
  bkContentType.b   ; In, specifies whether bkContent is an image or a colorref 
  txtColor.l        ; In, specifies desired text color for message box 
  bannerImage.l     ; In, specifies a #Image to use as a banner 
  delayTime.l       ; In, specifies number of seconds to wait before auto-clicking the default button 
  defaultButton.l   ; In, specifies the default button 
  modalLevel.b      ; In, specifiels modality desired 
  silent.b          ; In, specifies no "ding" when messagebox appears. Only for non-icon messageboxes. 
  ;------------------------------------------------- 
  ;    Variables for Internal Use Only 
  ;------------------------------------------------- 
  hwndMain.l        ; reserved, do not use 
  hwndIcon.l        ; reserved, do not use 
  timerThreadID.l   ; reserved, do not use 
  textGadgetID.l    ; reserved, do not use 
  defaultHwnd.l     ; reserved, do not use 
  defaultCtrlID.l   ; reserved, do not use 
  defaultHwndName.s ; reserved, do not use 
  staticBrush.l     ; reserved, do not use 
  timingBrush.l     ; reserved, do not use 
  bkImageID.l       ; reserved, do not use  
  timingBkImageID.l ; reserved, do not use 
  iconBkImageID.l   ; reserved, do not use 
  iconBrush.l       ; reserved, do not use 
  staticBkImageID.l ; reserved, do not use 
  cx.l              ; reserved, do not use 
  cy.l              ; reserved, do not use 
EndStructure 

Global mmb_Hook, gMMB_DATA_RESERVED.MMBDATA , mmb_ForcedResult=0 

Procedure MMB_dlgProc(hwnd, msg, wparam, lparam) 
  oldproc = GetProp_(hwnd, "oldproc") 
  Select msg 
  
    Case #WM_CLOSE 
      DestroyWindow_(hwnd) 
      mmb_ForcedResult = 1 

    Case #WM_CTLCOLORSTATIC 
  
      SetBkMode_(wparam, #TRANSPARENT) 
      SetTextColor_(wParam, gMMB_DATA_RESERVED\txtColor) 
      
      Select GetDlgCtrlID_(lparam) 
        Case $FFFF 
          ProcedureReturn gMMB_DATA_RESERVED\staticBrush 
          
        Case gMMB_DATA_RESERVED\textGadgetID 
          ProcedureReturn gMMB_DATA_RESERVED\timingBrush 
          
        Case GetDlgCtrlID_(gMMB_DATA_RESERVED\hwndIcon) 
          ProcedureReturn gMMB_DATA_RESERVED\iconBrush 
          
      EndSelect 
    
    Case #WM_NCDESTROY 
      RemoveProp_(hwnd, "oldproc") 
      
      DeleteObject_(gMMB_DATA_RESERVED\staticBrush) 
      
      If gMMB_DATA_RESERVED\delayTime 
        DeleteObject_(gMMB_DATA_RESERVED\timingBrush) 
        If gMMB_DATA_RESERVED\timingBkImageID 
          If IsImage(gMMB_DATA_RESERVED\timingBkImageID) 
            FreeImage(gMMB_DATA_RESERVED\timingBkImageID) 
          EndIf 
        EndIf 
      EndIf 
      
      If gMMB_DATA_RESERVED\bkImageID 
        If IsImage(gMMB_DATA_RESERVED\bkImageID) 
          FreeImage(gMMB_DATA_RESERVED\bkImageID) 
        EndIf 
      EndIf 
      
      If gMMB_DATA_RESERVED\staticBkImageID 
        If IsImage(gMMB_DATA_RESERVED\staticBkImageID) 
          FreeImage(gMMB_DATA_RESERVED\staticBkImageID) 
        EndIf 
      EndIf      

      If gMMB_DATA_RESERVED\iconBkImageID 
        DeleteObject_(gMMB_DATA_RESERVED\iconBrush) 
        If IsImage(gMMB_DATA_RESERVED\iconBkImageID) 
          FreeImage(gMMB_DATA_RESERVED\iconBkImageID) 
        EndIf 
      EndIf      
      
      If gMMB_DATA_RESERVED\timerThreadID 
        If IsThread(gMMB_DATA_RESERVED\timerThreadID) 
          KillThread(gMMB_DATA_RESERVED\timerThreadID) 
        EndIf 
      EndIf 
        
      If gMMB_DATA_RESERVED\textGadgetID 
        If IsGadget(gMMB_DATA_RESERVED\textGadgetID) 
          FreeGadget(gMMB_DATA_RESERVED\textGadgetID) 
        EndIf 
      EndIf 
            
  EndSelect 
  
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam) 
  
EndProcedure 

Procedure MMB_GetDefaultHwnd(hwnd, lparam) 
  Static buttoncount = 0 
  If lparam = -1 
    buttoncount = 0 
    ProcedureReturn 0 
  EndIf 
  wc$ = Space(255) 
  GetClassName_(hwnd, @wc$, 250) 
  If UCase(wc$) = "BUTTON" 
    buttoncount+1 
    If buttoncount = gMMB_DATA_RESERVED\defaultButton 
      gMMB_DATA_RESERVED\defaultHwnd = hwnd 
      gMMB_DATA_RESERVED\defaultCtrlID = GetDlgCtrlID_(hwnd) 
      GetWindowText_(hwnd, @wc$,250) 
      gMMB_DATA_RESERVED\defaultHwndName = RemoveString(wc$,"&") 
      ProcedureReturn 0 
    EndIf 
  EndIf 
  ProcedureReturn 1 
EndProcedure 

Procedure MMB_TimerThread(secondsremaining) 
  t=ElapsedMilliseconds() 
  Repeat 
    Delay(1000) 
    secondsremaining-1 
    SetGadgetText(gMMB_DATA_RESERVED\textGadgetID, gMMB_DATA_RESERVED\defaultHwndName+" = "+Str(secondsremaining)) 
  Until secondsremaining <=0 
  PostMessage_(gMMB_DATA_RESERVED\hwndmain, #WM_SYSCOMMAND, #SC_HOTKEY, gMMB_DATA_RESERVED\hwndmain) 
  Delay(200) 
  PostMessage_(gMMB_DATA_RESERVED\defaultHwnd, #WM_LBUTTONDOWN,0,0) 
  Delay(200) 
  PostMessage_(gMMB_DATA_RESERVED\defaultHwnd, #WM_LBUTTONUP,0,0) 
  Delay(200) 
  If IsWindow_(gMMB_DATA_RESERVED\hwndmain) 
    SendMessage_(gMMB_DATA_RESERVED\hwndmain, #WM_SYSCOMMAND, #SC_CLOSE, 0) 
  EndIf 
EndProcedure 

Procedure ThemesEnabled() 
  dlv.DLLVERSIONINFO 
  dlv\cbsize=SizeOf(DLLVERSIONINFO) 
  lib=OpenLibrary(#PB_Any,"comctl32.dll") 
  If lib 
    CallFunction(lib,"DllGetVersion",@dlv) 
    DLLVersion = dlv\dwMajorVersion 
    CloseLibrary(lib) 
  EndIf 
  If DLLVersion = 6 
    ProcedureReturn 1 
  Else 
    ProcedureReturn 0 
  EndIf 
EndProcedure 

Procedure MMB_CBTHookProc(nCode, wParam, lParam) 

  Static hwndmain 
  Select nCode 
  
    Case #HCBT_CREATEWND 
      *pcbt.CBT_CREATEWND = lParam 
      *pcs.CREATESTRUCT = *pcbt\lpcs 
      
      Select *pcs\lpszClass 
      
        Case 32770  ; Dialog Window 
          hwndmain = wParam 
          gMMB_DATA_RESERVED\hwndmain = wParam 
  
          If Not (gMMB_DATA_RESERVED\x=0 And gMMB_DATA_RESERVED\y=0) 
            *pcs\x = gMMB_DATA_RESERVED\x    
            *pcs\y = gMMB_DATA_RESERVED\y 
          EndIf    
          If gMMB_DATA_RESERVED\delayTime 
            *pcs\cy + 20 
          EndIf 
          If gMMB_DATA_RESERVED\bannerImage 
            *pcs\cy + ImageHeight(gMMB_DATA_RESERVED\bannerImage) 
          EndIf          
          gMMB_DATA_RESERVED\cx = *pcs\cx - 2*GetSystemMetrics_(#SM_CXFIXEDFRAME) 
          gMMB_DATA_RESERVED\cy = *pcs\cy - 2*GetSystemMetrics_(#SM_CYFIXEDFRAME)-GetSystemMetrics_(#SM_CYCAPTION) 
          SetProp_(wparam, "oldproc", SetWindowLong_(wparam,#GWL_WNDPROC,@MMB_dlgProc())) 
          
        Case 49177 ; Static Control 
          If GetWindowLong_(wParam, #GWL_STYLE) & #SS_BITMAP 
            gMMB_DATA_RESERVED\hwndIcon = wParam 
          EndIf 
          
          If gMMB_DATA_RESERVED\bannerImage 
            *pcs\y + ImageHeight(gMMB_DATA_RESERVED\bannerImage) 
          EndIf        
          
        Default 
          If gMMB_DATA_RESERVED\bannerImage 
            *pcs\y + ImageHeight(gMMB_DATA_RESERVED\bannerImage) 
          EndIf 
            
      EndSelect 
      
    Case #HCBT_ACTIVATE 
  
      If wParam = hwndmain 
      
        UnhookWindowsHookEx_(mmb_Hook) 
        
        MMB_GetDefaultHwnd(0, -1) ; clear the static buttoncount var before enumerating the controls 
        EnumChildWindows_(hwndmain, @MMB_GetDefaultHwnd(), 0) 
          
        Select gMMB_DATA_RESERVED\bkContentType 
        
          Case #MMB_COLOR 
            img = CreateImage(#PB_Any, gMMB_DATA_RESERVED\cx, gMMB_DATA_RESERVED\cy, 32) 
            StartDrawing(ImageOutput(img)) 
              Box(0,0,gMMB_DATA_RESERVED\cx, gMMB_DATA_RESERVED\cy, gMMB_DATA_RESERVED\bkContent) 
            StopDrawing() 
            gMMB_DATA_RESERVED\bkImageID = img 
            
          Case #MMB_IMAGE 
            If IsImage(gMMB_DATA_RESERVED\bkContent) 
              tmp = CopyImage(gMMB_DATA_RESERVED\bkContent, #PB_Any) 
              ResizeImage(tmp,gMMB_DATA_RESERVED\cx,gMMB_DATA_RESERVED\cy) 
              gMMB_DATA_RESERVED\bkImageID = tmp 
            Else 
              gMMB_DATA_RESERVED\bkImageID = CreateImage(#PB_Any, gMMB_DATA_RESERVED\cx, gMMB_DATA_RESERVED\cy, 32) 
              StartDrawing(ImageOutput(gMMB_DATA_RESERVED\bkImageID)) 
                Box(0,0,gMMB_DATA_RESERVED\cx, gMMB_DATA_RESERVED\cy, GetSysColor_(#COLOR_BTNFACE)) 
              StopDrawing() 
            EndIf 
            
          Case #MMB_TEST 
            img = CreateImage(#PB_Any, gMMB_DATA_RESERVED\cx, gMMB_DATA_RESERVED\cy, 32) 
            StartDrawing(ImageOutput(img)) 
              Box(0,0,gMMB_DATA_RESERVED\cx, gMMB_DATA_RESERVED\cy, GetSysColor_(#COLOR_BTNFACE)) 
            StopDrawing()        
            gMMB_DATA_RESERVED\bkImageID = img  
            tmp$ = "w"+Str(gMMB_DATA_RESERVED\cx)+",h"+Str(gMMB_DATA_RESERVED\cy) 
            SetWindowText_(hwndmain, @tmp$) 
                        
          Case #MMB_NOBACKGROUND 
            gMMB_DATA_RESERVED\bkImageID = CreateImage(#PB_Any, gMMB_DATA_RESERVED\cx, gMMB_DATA_RESERVED\cy, 32) 
            StartDrawing(ImageOutput(gMMB_DATA_RESERVED\bkImageID)) 
              Box(0,0,gMMB_DATA_RESERVED\cx, gMMB_DATA_RESERVED\cy, GetSysColor_(#COLOR_BTNFACE)) 
            StopDrawing() 
            
        EndSelect 
        
        If gMMB_DATA_RESERVED\bannerImage 
          ; Create left and right extension brushes 
          lbrush = GrabImage(gMMB_DATA_RESERVED\bannerImage, #PB_Any,0,0,1,ImageHeight(gMMB_DATA_RESERVED\bannerImage)) 
          rbrush = GrabImage(gMMB_DATA_RESERVED\bannerImage, #PB_Any,ImageWidth(gMMB_DATA_RESERVED\bannerImage)-1,0,1,ImageHeight(gMMB_DATA_RESERVED\bannerImage)) 
          leftbrush = CreatePatternBrush_(ImageID(lbrush)) 
          rightbrush = CreatePatternBrush_(ImageID(rbrush)) 
          
          ; Create and draw the banner image 
          banner = CreateImage(#PB_Any, gMMB_DATA_RESERVED\cx, ImageHeight(gMMB_DATA_RESERVED\bannerImage), #PB_Image_DisplayFormat) 
          lpos = ImageWidth(banner)/2 - ImageWidth(gMMB_DATA_RESERVED\bannerImage)/2 
          rpos = lpos + ImageWidth(gMMB_DATA_RESERVED\bannerImage) 
          With lbr.RECT 
            \left=0 : \top=0 : \right=lpos : \bottom=ImageHeight(gMMB_DATA_RESERVED\bannerImage) 
          EndWith 
          With rbr.RECT 
            \left=rpos : \top=0 : \right=ImageWidth(banner) : \bottom=ImageHeight(gMMB_DATA_RESERVED\bannerImage) 
          EndWith 
          hdc = StartDrawing(ImageOutput(banner)) 
            FillRect_(hdc, lbr, leftbrush) 
            FillRect_(hdc, rbr, rightbrush) 
            DrawImage(ImageID(gMMB_DATA_RESERVED\bannerImage),lpos,0) 
            Line(0,0,ImageWidth(banner)-1,0,RGB(157,157,161)) 
            Line(0,0,0,ImageHeight(banner)-1,RGB(157,157,161)) 
            Line(1,1,ImageWidth(banner)-3,0,RGB(113,111,100)) 
            Line(1,1,0,ImageHeight(banner)-3,RGB(113,111,100)) 
            Line(ImageWidth(banner)-1,0,0,ImageHeight(banner),#White) 
            Line(0,ImageHeight(banner)-1,ImageWidth(banner),0,#White) 
            Line(ImageWidth(banner)-2,1,0,ImageHeight(banner)-2,RGB(241,239,226)) 
            Line(1,ImageHeight(banner)-2,ImageWidth(banner)-2,0,RGB(241,239,226)) 
          StopDrawing() 
          DeleteObject_(leftbrush) 
          DeleteObject_(rightbrush) 
          FreeImage(lbrush) 
          FreeImage(rbrush)  
          StartDrawing(ImageOutput(gMMB_DATA_RESERVED\bkImageID)) 
            DrawImage(ImageID(banner),0,0) 
          StopDrawing() 
          FreeImage(banner)      
        EndIf 
        
        CompilerIf #PB_Compiler_Version < 430 
          CreateGadgetList(wParam)
        CompilerElse
          UseGadgetList(wParam)
        CompilerEndIf
        ig = ImageGadget(#PB_Any, 0,0,0,0,ImageID(gMMB_DATA_RESERVED\bkImageID)) 
        SetWindowPos_(GadgetID(ig), #HWND_BOTTOM,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE) 
        SetWindowLong_(GadgetID(ig),#GWL_STYLE,GetWindowLong_(GadgetID(ig),#GWL_STYLE)|#WS_CLIPSIBLINGS) 
        DisableGadget(ig, #True) 
        
        ; Icon background brush 
        If gMMB_DATA_RESERVED\hwndIcon 
          If Not ThemesEnabled() 
            gMMB_DATA_RESERVED\iconBrush = CreatePatternBrush_(ImageID(gMMB_DATA_RESERVED\bkImageID)) 
          Else 
            GetWindowRect_(gMMB_DATA_RESERVED\hwndIcon, wr.RECT) 
            MapWindowPoints_(0, gMMB_DATA_RESERVED\hwndMain, wr, 2) 
            gMMB_DATA_RESERVED\iconBkImageID = GrabImage(gMMB_DATA_RESERVED\bkImageID, #PB_Any,wr\left,wr\top,wr\right-wr\left,wr\bottom-wr\top) 
            gMMB_DATA_RESERVED\iconBrush = CreatePatternBrush_(ImageID(gMMB_DATA_RESERVED\iconBkImageID)) 
          EndIf 
        EndIf 
        
        ; Messagebox text background brush 
        If Not ThemesEnabled() 
          gMMB_DATA_RESERVED\staticBrush = CreatePatternBrush_(ImageID(gMMB_DATA_RESERVED\bkImageID)) 
        Else 
          GetWindowRect_(GetDlgItem_(wparam, $FFFF), @wr.RECT) 
          MapWindowPoints_(0,gMMB_DATA_RESERVED\hwndMain,@wr,2) 
          gMMB_DATA_RESERVED\staticBkImageID = GrabImage(gMMB_DATA_RESERVED\bkImageID,#PB_Any,wr\left,wr\top,gMMB_DATA_RESERVED\cx-wr\left,wr\bottom-wr\top)      
          gMMB_DATA_RESERVED\staticBrush = CreatePatternBrush_(ImageID(gMMB_DATA_RESERVED\staticBkImageID)) 
        EndIf 
        
        If gMMB_DATA_RESERVED\delayTime 
          gMMB_DATA_RESERVED\textGadgetID = TextGadget(#PB_Any, 0,gMMB_DATA_RESERVED\cy-22,gMMB_DATA_RESERVED\cx,20, gMMB_DATA_RESERVED\defaultHwndName+" = "+Str(gMMB_DATA_RESERVED\delayTime),#SS_CENTER) 
          exstyle = GetWindowLong_(gMMB_DATA_RESERVED\textGadgetID, #GWL_EXSTYLE)    
          SetWindowLong_(gMMB_DATA_RESERVED\textGadgetID, #GWL_EXSTYLE, exstyle | #WS_EX_NOPARENTNOTIFY) 
            
          ; Seconds remaining text background brush 
          If Not ThemesEnabled() 
            gMMB_DATA_RESERVED\timingBrush = CreatePatternBrush_(ImageID(gMMB_DATA_RESERVED\bkImageID)) 
          Else 
            GetWindowRect_(GadgetID(gMMB_DATA_RESERVED\textGadgetID), @wr.RECT) 
            MapWindowPoints_(0,gMMB_DATA_RESERVED\hwndMain,@wr,2) 
            gMMB_DATA_RESERVED\timingBkImageID = GrabImage(gMMB_DATA_RESERVED\bkImageID,#PB_Any,wr\left,wr\top,gMMB_DATA_RESERVED\cx-wr\left,wr\bottom-wr\top)      
            gMMB_DATA_RESERVED\timingBrush = CreatePatternBrush_(ImageID(gMMB_DATA_RESERVED\timingBkImageID)) 
          EndIf 
          
          ; Start the countdown timer 
          If Not IsThread(gMMB_DATA_RESERVED\timerThreadID)          
            gMMB_DATA_RESERVED\timerThreadID = CreateThread(@MMB_TimerThread(), gMMB_DATA_RESERVED\delayTime) 
          EndIf 
        EndIf 
        
        ProcedureReturn 0 
      EndIf 
      
  EndSelect 
  
  ProcedureReturn CallNextHookEx_(mmb_Hook, nCode, wParam, lParam) 
  
 EndProcedure 

ProcedureDLL.l ManagedMessageBox(title$, text$, *mmb_data_in.MMBDATA, flags=0) 

  With gMMB_DATA_RESERVED 
    \x               = *mmb_data_in\x          
    \y               = *mmb_data_in\y              
    \bkContent       = *mmb_data_in\bkContent      
    \bkContentType   = *mmb_data_in\bkContentType    
    \txtColor        = *mmb_data_in\txtColor      
    \bannerImage     = *mmb_data_in\bannerImage 
    \delayTime       = *mmb_data_in\delayTime        
    \defaultButton   = *mmb_data_in\defaultButton    
    \modalLevel      = *mmb_data_in\modalLevel      
    \silent          = *mmb_data_in\silent 
    \hwndMain        = 0 
    \hwndIcon        = 0 
    \timerThreadID   = 0 
    \textGadgetID    = 0    
    \defaultHwnd     = 0      
    \defaultCtrlID   = 0 
    \defaultHwndName = "" 
    \staticBrush     = 0 
    \timingBrush     = 0 
    \iconBrush       = 0  
    \bkImageID       = 0 
    \staticBkImageID = 0 
    \timingBkImageID = 0        
    \iconBkImageID   = 0 
    \cx              = 0 
    \cy              = 0 
  EndWith 
  
  If gMMB_DATA_RESERVED\delayTime 
    gMMB_DATA_RESERVED\modalLevel = 1 
  EndIf 
  
  Select gMMB_DATA_RESERVED\defaultButton 
    Case 0 
      gMMB_DATA_RESERVED\defaultButton = 1 
      flags = flags|#MB_DEFBUTTON1 
    Case 2 
      flags = flags|#MB_DEFBUTTON2 
    Case 3 
      flags = flags|#MB_DEFBUTTON3 
    Default 
      flags = flags|#MB_DEFBUTTON1 
  EndSelect 
  If gMMB_DATA_RESERVED\BkContent 
    If Not gMMB_DATA_RESERVED\BkContentType 
      gMMB_DATA_RESERVED\BkContentType = #MMB_COLOR 
    EndIf 
  EndIf  
  If gMMB_DATA_RESERVED\modalLevel 
    flags = flags | #MB_SYSTEMMODAL 
  EndIf 
  If gMMB_DATA_RESERVED\silent 
    flags = flags | $C0 
  EndIf 
  mmb_Hook = SetWindowsHookEx_(#WH_CBT, @MMB_CBTHookProc(), #Null, GetCurrentThreadId_()) 
  result = MessageBox_(0, text$, title$, flags) 
  If mmb_ForcedResult 
    result = gMMB_DATA_RESERVED\defaultCtrlID 
    mmb_ForcedResult = 0 
  EndIf 
  
  ProcedureReturn result 
  
EndProcedure 
Test program:

Code: Select all

IncludeFile "ManagedMessageBox20.pbi"

myimage = CreateImage(#PB_Any,257,95) ; got the size using #MMB_TEST
StartDrawing(ImageOutput(myimage))
  Box(0,0,257,95, #White)
  Circle(257/2, 95/2, 90/2, RGB(235,245,235))
StopDrawing()

With mmb_data.MMBDATA
  \x = 100
  \y = 100
  \BkContent = myimage
  \BkContentType = #MMB_IMAGE
  \txtcolor = #Red
  \defaultButton = 2
  \delayTime = 5
  \modalLevel = 1
  \silent = 1
EndWith

Debug ManagedMessageBox("Announcement:", "Holy insect bites, Batman! It's the Green Hornet!", mmb_data, #MB_ABORTRETRYIGNORE )
Last edited by netmaestro on Mon Dec 22, 2008 12:44 am, edited 25 times in total.
BERESHEIT
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Very useful, thanks. :)
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
harff182
Enthusiast
Enthusiast
Posts: 105
Joined: Thu Dec 08, 2005 4:58 pm
Location: Duesseldorf, Germany

Post by harff182 »

moin, moin...

Any idea, why for line 242 of the include I get Line 242: Invalid name: same as an external command ?
Any known probs with libs, e.g. from PBOSL ?

tia...
Sorry 4 my poor English, it's the only one I learned 40 years ago...
since 17.12.08: XPHome(SP3) + PB 4.30
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

If you have the old version of ManagedMessageBox in your PureBasic\PureLibraries\UserLibraries folder, it has to be deleted and then restart the compiler.
BERESHEIT
harff182
Enthusiast
Enthusiast
Posts: 105
Joined: Thu Dec 08, 2005 4:58 pm
Location: Duesseldorf, Germany

Post by harff182 »

Ooooh yeahhh !!
Thanks...
Sorry 4 my poor English, it's the only one I learned 40 years ago...
since 17.12.08: XPHome(SP3) + PB 4.30
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Fixed several bugs and problems, if you got this earlier today please get the latest version in the first post.
BERESHEIT
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

Thanks for the update.

I also noticed you placed the date of your update as "June 24, 2008" in your posting, have you worked out any of the remaining bugs in your time-machine? :wink:
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Hehe, I've been coding too long today!
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Fixed one more bug, let's hope that's all of them.
BERESHEIT
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Wowsie. Most impressive. Code too :D

Many thanks for all your contributions.

cheers
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Fixed a small leak where the textgadget used for the remaining seconds wasn't being freed. Also removed some unused lines of code left over from an earlier development stage that are no longer necessary.

Updates are listed by date in bold in the first post. If you are using this library, please ensure that your copy contains the code from the latest update.
BERESHEIT
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Thanks for the update. :)
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

June 2: 2 bugs fixed and added banner support. See first post for details.
BERESHEIT
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

:shock: Hey, have I missed my birthday?

Code: Select all

; License:           Free, unrestricted, no warranty 
; 
; Last Update:       July 2, 2008 
; 
; Usage: Filling the MMMBDATA structure 
:lol:

Thanks for the very nice update!
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Fixed a bug in the Banner drawing where the left brush was also being used on the right side. Would affect banners with a horizontal gradient.
BERESHEIT
Post Reply