Page 1 of 1

Displaying a bitmap in a child within a parent window?

Posted: Wed Jul 02, 2003 9:19 pm
by Kale
Im trying to display a bitmap within the little mini monitor in the screensaver tab of the 'Display Properties' dialog on WinXP, but i'm having little luck. I've been trying to get this to work for months now and its really doing me in. I have read lots of working examples using WinAPI but i really don't understand them and i can't seem to convert them to make them more simple :( I would be very gratefull if someone could point me in the right direction. Basically i need to display a bitmap inside a window which is a child of the 'mini monitor' window and then pass control of all events to the parents callback. sounds easy? not for me :?

This is what i have been trying:

Code: Select all

;===========================================================================
;-CONSTANTS
;===========================================================================

#WINDOW_PREVIEW = 0

;===========================================================================
;-GLOBAL FLAGS / VARIABLES / STRUCTURES / ARRAYS
;===========================================================================

Global parameter.s
Global prevWinHndlString.s
Global prevWinHndl.l

parameter = UCase(ProgramParameter())
If Len(parameter) > 2
    prevWinHndlString = RemoveString(parameter, Left(parameter, 3), 1)
    parameter = RemoveString(parameter, Left(parameter, 1), 1)
    parameter = Left(parameter, 1)
Else
    parameter = RemoveString(parameter, Left(parameter, 1), 1)
    prevWinHndlString = ProgramParameter()
    If FindString(prevWinHndlString, "-", 0) <> 0 : prevWinHndlString = RemoveString(prevWinHndlString, "-", 1) : EndIf
    If FindString(prevWinHndlString, "/", 0) <> 0 : prevWinHndlString = RemoveString(prevWinHndlString, "/", 1) : EndIf
EndIf
prevWinHndl = Val(prevWinHndlString)

;===========================================================================
;-PROCEDURES
;===========================================================================

;simple error checking
Procedure HandleError(result, text.s)
    If result = 0 : MessageRequester("Error", text, #PB_MessageRequester_Ok) : End : EndIf
EndProcedure

;execute the preview in the little mini monitor in 'Display Properties'
Procedure ExecutePreview()
    previewWindowSize.RECT
    GetClientRect_(prevWinHndl, @previewWindowSize)
    OpenWindow(#WINDOW_PREVIEW, 0, 0, previewWindowSize\right, previewWindowSize\bottom, #PB_Window_BorderLess | #WS_CHILD | #WS_VISIBLE, "Preview", prevWinHndl)
    CatchImage(1, ?PreviewImage)
    HandleError(CreateGadgetList(WindowID(#WINDOW_PREVIEW)), "Gadget list in preview window could not be created!")
    ImageGadget(1, 0, 0, previewWindowSize\right, previewWindowSize\bottom, UseImage(1))
    CloseGadgetList()
    Repeat
        EventID.l = WaitWindowEvent()
    Until EventID = #PB_EventCloseWindow
EndProcedure

;deal with the parameters passed to this program
Select parameter
    Case "P" ;when the preview is requested in the screensaver dialog
        ExecutePreview()
EndSelect

;===========================================================================
;-BINARY INCLUDES
;===========================================================================
    
PreviewImage:
    IncludeBinary "preview.bmp"
Compile this into C:\windows\system32 as whatever.src to make it appear in the screensaver drop down menu. BTW it doesn't work, but it should? Also this program doesn't quit when the parent is closed?

Posted: Wed Jul 02, 2003 11:23 pm
by Kale
hmmm... i've tried this approach too, using a bit of WinAPI:

Code: Select all

;===========================================================================
;-CONSTANTS
;===========================================================================

#WINDOW_PREVIEW = 0

;===========================================================================
;-GLOBAL FLAGS / VARIABLES / STRUCTURES / ARRAYS
;===========================================================================

Global parameter.s
Global prevWinHndlString.s
Global prevWinHndl.l

parameter = UCase(ProgramParameter())
If Len(parameter) > 2
    prevWinHndlString = RemoveString(parameter, Left(parameter, 3), 1)
    parameter = RemoveString(parameter, Left(parameter, 1), 1)
    parameter = Left(parameter, 1)
Else
    parameter = RemoveString(parameter, Left(parameter, 1), 1)
    prevWinHndlString = ProgramParameter()
    If FindString(prevWinHndlString, "-", 0) <> 0 : prevWinHndlString = RemoveString(prevWinHndlString, "-", 1) : EndIf
    If FindString(prevWinHndlString, "/", 0) <> 0 : prevWinHndlString = RemoveString(prevWinHndlString, "/", 1) : EndIf
EndIf
prevWinHndl = Val(prevWinHndlString)

;===========================================================================
;-PROCEDURES
;===========================================================================

;simple error checking
Procedure HandleError(result, text.s)
    If result = 0 : MessageRequester("Error", text, #PB_MessageRequester_Ok) : End : EndIf
EndProcedure

;execute the preview in the little mini monitor in 'Display Properties'
Procedure ExecutePreview()
    previewWindowSize.RECT
    GetClientRect_(prevWinHndl, @previewWindowSize)
    SHwnd = OpenWindow(#WINDOW_PREVIEW, 0, 0, previewWindowSize\right, previewWindowSize\bottom, #PB_Window_BorderLess | #WS_CHILD | #WS_VISIBLE, "Preview", prevWinHndl)
    HandleError(CreateGadgetList(WindowID(#WINDOW_PREVIEW)), "Gadget list in preview window could not be created!")
    CatchImage(1, ?PreviewImage)
    ImageGadget(1, 0, 0, previewWindowSize\right, previewWindowSize\bottom, UseImage(1))
    CloseGadgetList()
    
    lStyle.l = GetWindowLong_(SHwnd, #GWL_STYLE)
    lStyle = lStyle | #WS_CHILD
    SetWindowLong_(SHwnd, #GWL_STYLE, lStyle)
    SetParent_(SHwnd, prevWinHndl)
    SetWindowLong_(SHwnd, #GWL_HWNDPARENT, prevWinHndl)
    SetWindowPos_(SHwnd, #HWND_TOP, 0, 0, previewWindowSize\right, previewWindowSize\bottom, #SWP_NOZORDER | #SWP_NOACTIVATE | #SWP_SHOWWINDOW) 
EndProcedure

;deal with the parameters passed to this program
Select parameter
    Case "P" ;when the preview is requested in the screensaver dialog
        ExecutePreview()
EndSelect

;===========================================================================
;-BINARY INCLUDES
;===========================================================================
    
PreviewImage:
    IncludeBinary "preview.bmp"

Still no luck :(

Posted: Thu Jul 03, 2003 12:38 am
by VPureBasic
Hi Kale,

I looked to your code and, I wrote you a new one that will help you... I guess!

Code: Select all


    #WINDOW_MASTER  = 0 
    #WINDOW_MONITOR = 1

    CatchImage(1, ?PreviewImage)
    UseImage(1)
    Image_Width  = ImageWidth()
    Image_Height = ImageHeight()
    
    OpenWindow( #WINDOW_MASTER ,0,0,640,480,#PB_Window_SystemMenu|#PB_Window_Invisible,"Master" )
    OpenWindow( #WINDOW_MONITOR,20,20,Image_Width,Image_Height,0,"Preview" )
    
    WndFlags = #WS_CHILD|#WS_CLIPCHILDREN|#WS_CLIPSIBLINGS|#WS_VISIBLE|#PB_Window_TitleBar
    SetWindowStyles( #WINDOW_MONITOR, WndFlags,0 )
    SetWindowParent( 1, 0 )
    CreateGadgetList( WindowID( #WINDOW_MONITOR ) )
    
    ImageGadget(1, 0, 0, Image_Width, ImageHeight, UseImage(1)) 
    CloseGadgetList() 
  
    HideWindow( 1,0 )
    HideWindow( 0,0 )

    Repeat
          EW = WaitWindowEvent()
          WW = EventWindowID()
          
               If WW = 1
                    MoveWindow( 20,20 )
               EndIf 
    
    Until EW = #PB_EventCloseWindow
    
    End
    
    
    PreviewImage: 
    IncludeBinary "preview.bmp"
Roger

Posted: Thu Jul 03, 2003 6:17 pm
by Kale

Code: Select all

SetWindowStyles()
SetWindowParent()
?

VPureBasic, are you using user libs?

Posted: Thu Jul 03, 2003 7:01 pm
by tinman
It'll be VPureBasic's WindowEx user library (and maybe ScreenEx). Both on the resources site.

Posted: Thu Jul 10, 2003 8:44 pm
by Kale
Found the UserLib :) alas i can not use the SetParent() command as it does not accept handles :?

This is as far as i've got now, it seems to work up until a point. The bitmap is shown in the 'displays properties' window but when i close the temporary MessageRequester it crashes. I'm thinking i need to pass control of the child to the parent, so it can handle messages/events/main loop etc... but i thought thats what making it a child meant? Please, any ideas? this really is driving me nuts :x

Code: Select all

;===========================================================================
;-CONSTANTS
;===========================================================================

#WINDOW_PREVIEW = 0

;===========================================================================
;-GLOBAL FLAGS / VARIABLES / STRUCTURES / ARRAYS
;===========================================================================

Global parameter.s
Global prevWinHndlString.s
Global prevWinHndl.l

parameter = UCase(ProgramParameter())

If Len(parameter) > 2
    prevWinHndlString = RemoveString(parameter, Left(parameter, 3), 1)
    parameter = RemoveString(parameter, Left(parameter, 1), 1)
    parameter = Left(parameter, 1)
Else
    parameter = RemoveString(parameter, Left(parameter, 1), 1)
    prevWinHndlString = ProgramParameter()
    If FindString(prevWinHndlString, "-", 0) <> 0 : prevWinHndlString = RemoveString(prevWinHndlString, "-", 1) : EndIf
    If FindString(prevWinHndlString, "/", 0) <> 0 : prevWinHndlString = RemoveString(prevWinHndlString, "/", 1) : EndIf
EndIf
prevWinHndl = Val(prevWinHndlString)

;===========================================================================
;-PROCEDURES
;===========================================================================

;simple error checking
Procedure HandleError(result, text.s)
    If result = 0 : MessageRequester("Error", text, #PB_MessageRequester_Ok) : End : EndIf
EndProcedure

;preview window callback
Procedure PreviewCallback(Wnd, Message, wParam, lParam) 
    Select Message
        Case #WM_CLOSE
            Destroywindow_(Wnd)
            End 
    EndSelect
    Result = DefWindowProc_(Wnd, Message, wParam, lParam) 
    ProcedureReturn Result
EndProcedure

;execute the preview in the little mini monitor in 'Display Properties'
Procedure ExecutePreview()
    previewWindowSize.RECT
    GetClientRect_(prevWinHndl, @previewWindowSize)
    CatchImage(1, ?PreviewImage)
    SHwnd = OpenWindow(#WINDOW_PREVIEW, 0, 0, previewWindowSize\right, previewWindowSize\bottom, 0, "Preview")
    PreviewWindowFlags.l = #PB_Window_BorderLess | #WS_CHILD | #WS_CLIPCHILDREN | #WS_CLIPSIBLINGS | #WS_VISIBLE
    SetWindowStyles(#WINDOW_PREVIEW, PreviewWindowFlags, 0)
    SetParent_(SHwnd, prevWinHndl)
    HandleError(CreateGadgetList(SHwnd), "Gadget list in preview window could not be created!")
    ImageGadget(1, 0, 0, previewWindowSize\right, previewWindowSize\bottom, UseImage(1))
    
    MessageRequester("Info", "Displays image, if you press ok it vanishes!", #PB_MessageRequester_Ok)

EndProcedure

;deal with the parameters passed to this program
Select parameter
    Case "" ;double clicked
        End
    Case "A" ;check password
        End
    Case "C" ;'Settings' button clicked in the screensaver dialog
        End
    Case "P" ;when the preview is requested in the screensaver dialog by selecting this screensaver
        ExecutePreview()
    Case "S" ;launch the main screensaver after an interval or by pressing 'Preview' in the dialog
        End
EndSelect

;===========================================================================
;-BINARY INCLUDES
;===========================================================================
    
PreviewImage:
    IncludeBinary "preview.bmp"


Posted: Thu Jul 10, 2003 11:53 pm
by VPureBasic
Hi Kale,

Code: Select all

Found the UserLib  alas i can not use the SetParent() command as it does not accept handles 
U do not need Handles too... Only The Window Number As you used to OpenWindow( #Wnd... ) and the #parent...

Roger