Displaying a bitmap in a child within a parent window?

Just starting out? Need help? Post your questions and find answers here.
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Displaying a bitmap in a child within a parent window?

Post 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?
--Kale

Image
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post 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 :(
--Kale

Image
VPureBasic
User
User
Posts: 59
Joined: Fri Apr 25, 2003 6:09 pm
Location: Quebec - Canada

Post 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
Everything is possible with PureBASIC... All you're missing is imagination!
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Code: Select all

SetWindowStyles()
SetWindowParent()
?

VPureBasic, are you using user libs?
--Kale

Image
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

It'll be VPureBasic's WindowEx user library (and maybe ScreenEx). Both on the resources site.
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post 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"

--Kale

Image
VPureBasic
User
User
Posts: 59
Joined: Fri Apr 25, 2003 6:09 pm
Location: Quebec - Canada

Post 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
Everything is possible with PureBASIC... All you're missing is imagination!
Post Reply