Announcement

Collapse
No announcement yet.

Options Please: Dialog As An Image Container

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Options Please: Dialog As An Image Container

    "Write Something ..."
    Ok!
    Here's what I got working so far:
    Code:
    #COMPILE EXE
    #DIM ALL
    
    '------------------------------------------------------------------------------
    '   ** Includes **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN INCLUDES
    #IF NOT %DEF(%WINAPI)
        #INCLUDE "WIN32API.INC"
    #ENDIF
    #INCLUDE "..\GdiPlus.inc"
    #PBFORMS END INCLUDES
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Constants **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN CONSTANTS
    %IDD_ShowImage      =  101
    %IDM_FILE_EXIT      = 1001
    %IDM_FILE_QUIT      = 1002
    %IDM_FULLSCREEN     = 1003
    %IDR_ACCELERATOR1   =  103
    %IDR_MENU1          =  102
    #PBFORMS END CONSTANTS
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Declarations **
    '------------------------------------------------------------------------------
    
    TYPE MYPOINTS
        iWidth          AS LONG
        iHeight         AS LONG
    END TYPE
    
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Main Application Entry Point **
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
    LOCAL StartupInput AS GDIplusStartupInput
    LOCAL GDItoken     AS DWORD
    
        StartupInput.GDIplusVersion = 1
        IF GDIplusStartup(GDItoken, StartupInput, BYVAL %NULL) <> 0 THEN
            MSGBOX "No GDI+"
            EXIT FUNCTION
        END IF
    
        ShowShowImage %HWND_DESKTOP
    
        GDIplusShutdown GDItoken
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** CallBacks **
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowShowImageProc()
    LOCAL ImageFileName, uFileName  AS STRING
    STATIC hSourceImage             AS DWORD
    STATIC BigDialog                AS LONG
    STATIC oldw, oldh, oldx, oldy   AS LONG
    LOCAL hResult                   AS LONG
    LOCAL DeskSize                  AS MYPOINTS
    
    
        SELECT CASE AS LONG CB.MSG
            CASE %WM_INITDIALOG
                ' Initialization handler
                ImageFileName = "path to your image file"
                uFileName = UCODE$(ImageFileName)
                hResult = GdipLoadImageFromFile(uFileName, BYREF hSourceImage)
                IF (hResult = 0) THEN
                    DrawImage CB.HNDL, hSourceImage
                END IF
    
            CASE %WM_DESTROY
                hResult = GdipDisposeImage(hSourceImage)
    
            CASE %WM_PAINT
                DrawImage CB.HNDL, hSourceImage
                FUNCTION = 1
    
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CB.WPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                    DrawImage CB.HNDL, hSourceImage
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                    DrawImage CB.HNDL, hSourceImage
                END IF
    
            CASE %WM_COMMAND
                ' Process control notifications
                SELECT CASE AS LONG CB.CTL
                    CASE %IDM_FILE_EXIT
                        DIALOG END CB.HNDL
    
                    CASE %IDM_FILE_QUIT
                        DIALOG END CB.HNDL
    
                    CASE %IDM_FULLSCREEN
                    BigDialog = BigDialog XOR 1
                    IF BigDialog THEN
                        DIALOG GET SIZE CB.HNDL TO oldw,oldh  'save the old w/h size of the dialog
                        DIALOG GET LOC CB.HNDL TO oldx,oldy  'save the old w/h size of the dialog
                        DESKTOP GET SIZE TO DeskSize.iWidth, DeskSize.iHeight
                        DIALOG SET LOC CB.HNDL, 0,0
                        DIALOG SET SIZE CB.HNDL, DeskSize.iWidth, DeskSize.iHeight
                        SetWindowPos(CB.HNDL, %HWND_Top, 0, 0, 0, 0, %SWP_NoMove OR %SWP_NoSize)  'on Top
                        DrawImage CB.HNDL, hSourceImage
                    ELSE
                        DIALOG SET LOC CB.HNDL, oldx,oldy
                        DIALOG SET SIZE CB.HNDL, oldw,oldh
                        SetWindowPos(CB.HNDL, %HWND_NoTopMost, 0, 0, 0, 0, %SWP_NoMove OR %SWP_NoSize)  'on Top
                        DrawImage CB.HNDL, hSourceImage
                    END IF
    
                END SELECT
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    
    SUB DrawImage(hDlg AS DWORD, hSourceImage AS DWORD)
    LOCAL hResult                   AS LONG
    LOCAL pGraphics, hdcGraphics    AS DWORD
    LOCAL imgSize, newSize          AS MYPOINTS
    LOCAL DeskSize                  AS MYPOINTS
    
        GdipGetImageWidth  hSourceImage, imgSize.iWidth
        GdipGetImageHeight  hSourceImage, imgSize.iHeight
        DIALOG GET CLIENT hDlg TO newSize.iWidth, newSize.iHeight
        hdcGraphics = GetDC(hDlg)
        hResult = GdipCreateFromHDC(hdcGraphics, pGraphics)
        IF (hResult = 0) THEN
            hResult = GdipDrawImageRectRectI(pGraphics, hSourceImage, _
                0, 0, newSize.iWidth, newSize.iHeight, _
                0, 0, imgSize.iWidth, imgSize.iHeight, _
                %UnitPixel)
        END IF
        hResult = GdipDisposeImage(pGraphics)
    END SUB
    
    
    '------------------------------------------------------------------------------
    '   ** Dialogs **
    '------------------------------------------------------------------------------
    FUNCTION ShowShowImage(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
    
    #PBFORMS BEGIN DIALOG %IDD_ShowImage->%IDR_MENU1->%IDR_ACCELERATOR1
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW PIXELS, hParent, "Show Me", 442, 413, 376, 343, %WS_POPUP OR _
            %WS_VISIBLE OR %DS_NOFAILCREATE OR %DS_SETFONT, _
            %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
            %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
    
        ' AttachMENU1 hDlg
    
        AttachACCELERATOR1 hDlg
    #PBFORMS END DIALOG
    
        DIALOG SHOW MODAL hDlg, CALL ShowShowImageProc TO lRslt
    
    #PBFORMS BEGIN CLEANUP %IDD_ShowImage
    #PBFORMS END CLEANUP
    
        FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Menus **
    '------------------------------------------------------------------------------
    FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD
    #PBFORMS BEGIN MENU %IDR_MENU1->%IDD_ShowImage
        LOCAL hMenu   AS DWORD
        LOCAL hPopUp1 AS DWORD
    
        MENU NEW BAR TO hMenu
        MENU NEW POPUP TO hPopUp1
        MENU ADD POPUP, hMenu, "File", hPopUp1, %MF_ENABLED
            MENU ADD STRING, hPopUp1, "Exit" + $TAB + "Alt+F4", %IDM_FILE_EXIT, _
                %MF_ENABLED
            MENU ADD STRING, hPopUp1, "Quit" + $TAB + "F1", %IDM_FILE_QUIT, _
                %MF_ENABLED
    
        MENU ATTACH hMenu, hDlg
    #PBFORMS END MENU
        FUNCTION = hMenu
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Accelerators **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN ASSIGNACCEL
    FUNCTION ASSIGNACCEL(tAccel AS ACCELAPI, BYVAL wKey AS WORD, BYVAL wCmd AS _
        WORD, BYVAL byFVirt AS BYTE) AS LONG
        tAccel.fVirt = byFVirt
        tAccel.key   = wKey
        tAccel.cmd   = wCmd
    END FUNCTION
    #PBFORMS END ASSIGNACCEL
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    FUNCTION AttachACCELERATOR1(BYVAL hDlg AS DWORD) AS DWORD
    #PBFORMS BEGIN ACCEL %IDR_ACCELERATOR1->%IDD_ShowImage
        LOCAL hAccel   AS DWORD
        LOCAL tAccel() AS ACCELAPI
        DIM   tAccel(1 TO 3) AS ACCELAPI
    
        ASSIGNACCEL tAccel(1), %VK_F4, %IDM_FILE_EXIT, %FVIRTKEY OR %FALT OR _
            %FNOINVERT
        ASSIGNACCEL tAccel(2), %VK_ESCAPE, %IDM_FILE_QUIT, %FVIRTKEY OR %FNOINVERT
        ASSIGNACCEL tAccel(3), %VK_F12, %IDM_FULLSCREEN, %FVIRTKEY OR %FNOINVERT
    
        ACCEL ATTACH hDlg, tAccel() TO hAccel
    #PBFORMS END ACCEL
        FUNCTION = hAccel
    END FUNCTION
    '------------------------------------------------------------------------------
    Code for full screen borrowed from a suggestion by Gary Greene.

    It works, sort of, as expected.

    However, I'd like to reduce the flicker when it's in full screen mode and you toggle (using ALT+TAB) to another window for a a look as something else.

    The results is what I expect, when in full screen (F12), the whole screen is the dialog, and because I'm not specifying that it be the "Top Most" window, it permits you to switch to other windows on the desktop and see the contents of other windows. But when switching back, it does this horrible double refresh of the screen. And the first refresh is the default color of the dialog, ...

    I know this is possible because I've got PicView and it doesn't do that.

    EDIT NOTATION: The include is in a parent folder of the project file, hence the ..\ usage.
    Attached Files
    Furcadia, an interesting online MMORPG in which you can create and program your own content.

  • #2
    Hi Colin,

    Try this mod..
    Code:
            CASE %WM_PAINT
     '            DrawImage CB.HNDL, hSourceImage
     '            FUNCTION = 1
     
            CASE %WM_ERASEBKGND
                DrawImage CB.HNDL, hSourceImage
                Function = 1
    Rgds, Dave

    Comment


    • #3
      Yea, don't trap both, either one or the other, ... (%100 processor usage.)

      That said, using the EraseBkGnd works much better than trapping the Paint.

      Also switching to using SDK window is much faster than the DDT engine, there's a more noticeable delay before the repaint occurs.
      Furcadia, an interesting online MMORPG in which you can create and program your own content.

      Comment


      • #4
        You might consider doing what you find in text editors (e.g. Notepad) and use a separate control which is always fills the client area of your dialog as what you really draw on.

        You can do this with DDT by ...
        Code:
           CONTROL ADD "static"    (size and location and style)
        What this does is give you complete control over the label ("static") control and the DDT engine won't do anything "DDT-special" within that control.

        It doesn't have to be a "static" control but since the only thing you have to do with it is draw it when needed (WM_DRAWITEM for an SS_OWNERDRAW) it should be good enough.

        It's a thought.




        Comment

        Working...
        X