Jump to content

Gui to preview a Gdi+ image (with scrollbars, gdi+, resizable gui etc...)


Recommended Posts

Hi everyone,
This question is to help me find out what I have to do, how some things are managed and point me in the right direction hopefully by not reinventing the wheel.

What I want to achieve is to be able to preview an image like in any image software viewer/editor.
I have a Gdi+ bitmap with size 1024x1024
I want to show it fullsize on a resizable window (let's say initial size is 256x256) with scrollbars

I want the user to be able to resize and/or use scrollbars to "navigate"/"move" in the image

The question is: how do I do It ?

here is a screen from irfan view with only what I need:
RRdbuOH.png

I don't know what I have to do in autoit to achieve this. In c# I would create some image displayer in a panel with scrollbars in a form and voila.
In autoit do I have to manage all the repainting, scrollbar, resizing ?
I mean, do I have to calculate the scrollbars position to know what part of the image I'm in an then redraw that part ?
What about resizing?
What if only a part of the image is masked by another window, do I have to redraw the whole thing or is there a way to just redraw the invalid part ?
How and where do I redraw the image/part of the image ? in the onPaint event ? (and what would that be in autoit).

etc...

I've never done anything like that before, some hints or a complete methodology would be really helpfull.
For now I can draw the GdiPlus bitmap in a gui with the same size as the image. (and from some udf I've see that the guy repainted the whole image in the following event GUIRegisterMsg(0xF, "") )

thx

Link to comment
Share on other sites

I found an old snippet on my disk:

;coded by UEZ 2012
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <GuiReBar.au3>
#include <GuiScrollBars.au3>
#include <GuiToolbar.au3>
#include <ScreenCapture.au3>
#include <ScrollBarConstants.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()
Global Enum $idNew = 1000, $idOpen, $idSave, $idHelper
Global Const $iImageW = @DesktopWidth, $iImageH = @DesktopHeight
Global Const $hBMP_ScreenCapture = _ScreenCapture_Capture("", 0, 0, $iImageW, $iImageH, False)
Global Const $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP_ScreenCapture)

Sleep(50)
Global Const $iW = 800, $iH = 600

Global Const $hGUI = GUICreate("Test", $iW, $iH)
Global Const $hToolbar = _GUICtrlToolbar_Create($hGUI)
Global Const $hReBar = _GUICtrlRebar_Create($hGUI, BitOR($CCS_TOP, $RBS_VARHEIGHT, $RBS_AUTOSIZE, $RBS_BANDBORDERS))

Global Const $height_delta = 37
Global Const $idPic = GUICtrlCreatePic("", 0, $height_delta + 2, $iW, $iH)
Global $hBitmap_tmp, $hHBitmap_tmp
$hBitmap_tmp = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
Global $hGfx_Context = _GDIPlus_ImageGetGraphicsContext($hBitmap_tmp)

_GUICtrlToolbar_AddBitmap($hToolbar, 1, -1, $IDB_STD_LARGE_COLOR)

_GUICtrlToolbar_AddButton($hToolbar, $idNew, $STD_FILENEW)
_GUICtrlToolbar_AddButton($hToolbar, $idOpen, $STD_FILEOPEN)
_GUICtrlToolbar_AddButton($hToolbar, $idSave, $STD_FILESAVE)
_GUICtrlToolbar_AddButtonSep($hToolbar)
_GUICtrlToolbar_AddButton($hToolbar, $idHelper, $STD_HELP)

_GUICtrlRebar_AddToolBarBand($hReBar, $hToolbar, "", 0)

Global Const $iVSscroll = _WinAPI_GetSystemMetrics(2)
Global Const $iHSscroll = _WinAPI_GetSystemMetrics(3)
Global Const $iYCaption = _WinAPI_GetSystemMetrics(4)
Global Const $iYFixedFrame = _WinAPI_GetSystemMetrics(8)
Global Const $iXFixedFrame = _WinAPI_GetSystemMetrics(7)

Global Const $iMetricsSumX = $iVSscroll  + $iXFixedFrame * 2
Global Const $iMetricsSumY = $iHSscroll +  $iYCaption + $iYFixedFrame

_GUIScrollBars_Init($hGUI)
_GUIScrollBars_SetScrollInfoMin($hGUI, $SB_HORZ, 0)
_GUIScrollBars_SetScrollInfoMax($hGUI, $SB_HORZ, $iImageW - $iW + 61 + $iMetricsSumX)
_GUIScrollBars_SetScrollInfoMin($hGUI, $SB_VERT, 0)
_GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, $iImageH - $iH + $iMetricsSumY + $height_delta - 1)

GUISetState(@SW_SHOW, $hGUI)

Global Const $STM_SETIMAGE = 0x0172
_WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBMP_ScreenCapture))

Global $IE_offset_x = 0, $IE_offset_y = 0

DrawImage($hGfx_Context, $hBitmap, $IE_offset_x, $IE_offset_y, $iW, $iH)

GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL_IE")
GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL_IE")


Do
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Until False

GUIRegisterMsg($WM_HSCROLL, "")
GUIRegisterMsg($WM_VSCROLL, "")

_WinAPI_DeleteObject($hBMP_ScreenCapture)
_GDIPlus_BitmapDispose($hBitmap_tmp)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hGfx_Context)
_GDIPlus_Shutdown()
Exit

Func WM_HSCROLL_IE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $lParam
    Local $Min, $Max, $Page, $TrackPos

    ; Get all the horizontal scroll bar information
    Local $tSCROLLINFO_X = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $Min = DllStructGetData($tSCROLLINFO_X, "nMin")
    $Max = DllStructGetData($tSCROLLINFO_X, "nMax")
    $Page = DllStructGetData($tSCROLLINFO_X, "nPage")

    ; Save the position for comparison later on
    $IE_offset_x = DllStructGetData($tSCROLLINFO_X, "nPos")
    $TrackPos = DllStructGetData($tSCROLLINFO_X, "nTrackPos")
    #forceref $Min, $Max
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Switch $nScrollCode

        Case $SB_LINELEFT ; user clicked left arrow
            DllStructSetData($tSCROLLINFO_X, "nPos", $IE_offset_x - 1)

        Case $SB_LINERIGHT ; user clicked right arrow
            DllStructSetData($tSCROLLINFO_X, "nPos", $IE_offset_x + 1)

        Case $SB_PAGELEFT ; user clicked the scroll bar shaft left of the scroll box
            DllStructSetData($tSCROLLINFO_X, "nPos", $IE_offset_x - $Page)

        Case $SB_PAGERIGHT ; user clicked the scroll bar shaft right of the scroll box
            DllStructSetData($tSCROLLINFO_X, "nPos", $IE_offset_x + $Page)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO_X, "nPos", $TrackPos)
    EndSwitch

;~    // Set the position and then retrieve it.  Due to adjustments
;~    //   by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO_X, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO_X)

    $IE_offset_x = DllStructGetData($tSCROLLINFO_X, "nPos")

    DrawImage($hGfx_Context, $hBitmap, $IE_offset_x, $IE_offset_y, $iW, $iH)
    $hHBitmap_tmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_tmp)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap_tmp))
    _WinAPI_DeleteObject($hHBitmap_tmp)

    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_HSCROLL_IE

Func WM_VSCROLL_IE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $lParam

    Local $Min, $Max, $Page, $TrackPos

;~  ; Get all the horizontal scroll bar information
    Local $tSCROLLINFO_Y = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO_Y, "nMin")
    $Max = DllStructGetData($tSCROLLINFO_Y, "nMax")
    $Page = DllStructGetData($tSCROLLINFO_Y, "nPage")
    ; Save the position for comparison later on
    $IE_offset_y = DllStructGetData($tSCROLLINFO_Y, "nPos")
    $TrackPos = DllStructGetData($tSCROLLINFO_Y, "nTrackPos")
    #forceref $Min, $Max
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Switch $nScrollCode

        Case $SB_LINELEFT ; user clicked left arrow
            DllStructSetData($tSCROLLINFO_Y, "nPos", $IE_offset_y - 1)

        Case $SB_LINERIGHT ; user clicked right arrow
            DllStructSetData($tSCROLLINFO_Y, "nPos", $IE_offset_y + 1)

        Case $SB_PAGELEFT ; user clicked the scroll bar shaft left of the scroll box
            DllStructSetData($tSCROLLINFO_Y, "nPos", $IE_offset_y - $Page)

        Case $SB_PAGERIGHT ; user clicked the scroll bar shaft right of the scroll box
            DllStructSetData($tSCROLLINFO_Y, "nPos", $IE_offset_y + $Page)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO_Y, "nPos", $TrackPos)
    EndSwitch

;~    // Set the position and then retrieve it.  Due to adjustments
;~    //   by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO_Y, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO_Y)

    $IE_offset_y = DllStructGetData($tSCROLLINFO_Y, "nPos")

    DrawImage($hGfx_Context, $hBitmap, $IE_offset_x, $IE_offset_y, $iW, $iH)
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_VSCROLL_IE

Func DrawImage($hGfx_Context, $hBitmap, $IE_offset_x, $IE_offset_y, $iW, $iH)
    _GDIPlus_GraphicsDrawImageRectRect($hGfx_Context, $hBitmap, $IE_offset_x, $IE_offset_y, $iW, $iH, 0, 0, $iW, $iH)
    $hHBitmap_tmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_tmp)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap_tmp))
    _WinAPI_DeleteObject($hHBitmap_tmp)
EndFunc

GUI resize is not included -> homework for you. ;)

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Hello again,

I've messed around with UEZ code after almost understanding all of it ;).

It's clever to use the GUICtrlCreatePic and set the picture ourselves.

But there is a strange behaviour with GUICtrlCreatePic and GUIScrollBars.

If we draw the scrollbars after the control, then the position of the control is moved. The left and top position from

GUICtrlCreatePic ( filename, left, top [, width [, height [, style = -1 [, exStyle = -1]]]] ) are not valid anymore. Setting the position with GUICtrlSetPos with the same values does not change anything.

Also the bigger the top value, the bigger the ctrl moves up... If anyone has an explanation for this.

I've only experimented with the top position, obviously adding the bottom scrollbar changes some things but why the bigger the value the bigger the change ?

here are some changes with top values and the upward move in pixels:

top  move

0  0

1 1

6 1

25 1

30 1

35 1

36 2

50 2

129 4

here is a simple code to show the problem. Press the "h" hotkey to toggle the scrollbars hiding.

;coded by UEZ 2012
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <GuiScrollBars.au3>
#include <ScreenCapture.au3>
#include <ScrollBarConstants.au3>
#include <WindowsConstants.au3>

HotKeySet ( "h" , "hidescrolls" )


_GDIPlus_Startup()

Global Const $iImageW = @DesktopWidth, $iImageH = @DesktopHeight
Global Const $hHBMP_ScreenCapture = _ScreenCapture_Capture("", 0, 0, $iImageW, $iImageH, False)
Global Const $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBMP_ScreenCapture)

Sleep(50)
; create window with client size 800x600
Global Const $iW = 800, $iH = 600
Global Const $hGUI = GUICreate("Test", $iW, $iH)
GUISetBkColor(0x00FF00, $hGUI)


Global $hBitmap_tmp, $hHBitmap_tmp
$hBitmap_tmp = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
Global $hGfx_Context = _GDIPlus_ImageGetGraphicsContext($hBitmap_tmp)

_GUIScrollBars_Init($hGUI)
_GUIScrollBars_SetScrollInfoMin($hGUI, $SB_HORZ, 0)
_GUIScrollBars_SetScrollInfoMax($hGUI, $SB_HORZ, $iImageW)
_GUIScrollBars_SetScrollInfoMin($hGUI, $SB_VERT, 0)
_GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, $iImageH)

Global Const $idPic = GUICtrlCreatePic("", 0, 500, $iW, $iH)


GUISetState(@SW_SHOW, $hGUI)

Global Const $STM_SETIMAGE = 0x0172
DrawImage($hGfx_Context, $hBitmap, 0, 0, $iW, $iH)

Do
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Until False

_WinAPI_DeleteObject($hHBMP_ScreenCapture)
_GDIPlus_BitmapDispose($hBitmap_tmp)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hGfx_Context)
_GDIPlus_Shutdown()
Exit

Func DrawImage($hGfx_Context, $hBitmap, $IE_offset_x, $IE_offset_y, $iW, $iH)
    _GDIPlus_GraphicsDrawImageRectRect($hGfx_Context, $hBitmap, $IE_offset_x, $IE_offset_y, $iW, $iH, 0, 0, $iW, $iH)
    $hHBitmap_tmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_tmp)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap_tmp))
    _WinAPI_DeleteObject($hHBitmap_tmp)
 EndFunc

 Func hidescrolls()
    Static Local $bHide = True
    If $bHide Then
      _GUIScrollBars_SetScrollInfoMin($hGUI, $SB_HORZ, 0)
      _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_HORZ, 0)
      _GUIScrollBars_SetScrollInfoMin($hGUI, $SB_VERT, 0)
      _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, 0)
      $bHide = False
   Else
      _GUIScrollBars_SetScrollInfoMin($hGUI, $SB_HORZ, 0)
      _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_HORZ, $iImageW)
      _GUIScrollBars_SetScrollInfoMin($hGUI, $SB_VERT, 0)
      _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, $iImageH)
;~    GUICtrlSetPos($idPic, 0, 500)
      $bHide = True
    EndIf
 EndFunc
Edited by darkweaver
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...