In "Pic"-Steuerlement srollen

  • Hallo,

    ich möchte in ein Pic-Steuerlement ($Pic1 = GUICtrlCreatePic...) ein Bild laden lassen. Wenn dieses jedoch zu groß ist, sollen Scrollbars erscheinen, um zu scrollen.

    Wie kann ich dieses Problem lösen?

    Ich hoffe ihr könnt mir helfen!

    LG K.K.

  • Hier ein Beispiel:

    Spoiler anzeigen
    [autoit]


    #include <WindowsConstants.au3>
    #include <ScrollBarConstants.au3>
    #include <Constants.au3>
    #include <GuiScrollBars.au3>
    #include <ScreenCapture.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $STM_SETIMAGE = 0x0172
    _GDIPlus_Startup()
    Global $hBMP_Screen = _ScreenCapture_Capture("", 0, 0, @DesktopWidth, @DesktopHeight)
    Global $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hBMP_Screen)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $bW = _GDIPlus_ImageGetWidth($hBmp)
    Global $bH = _GDIPlus_ImageGetHeight($hBmp)

    [/autoit] [autoit][/autoit] [autoit]

    Global $iW = @DesktopWidth * 0.5, $iH = @DesktopHeight * 0.5
    Global $hGUI = GUICreate("Test", $iW, $iH)
    Global $idPic = GUICtrlCreatePic("", $iW, $iH)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    Global $IE_offset_x, $IE_offset_y, $iNewH, $iNewW
    Global $hGfx_IE_BMP_Display, $hCtx_IE_BMP_Display
    Global $IE_ScrollbarH = False, $IE_ScrollbarV = False

    [/autoit] [autoit][/autoit] [autoit]

    PlacePicCtrl()

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = -3

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_BitmapDispose($hGfx_IE_BMP_Display)
    _GDIPlus_GraphicsDispose($hCtx_IE_BMP_Display)
    _GDIPlus_BitmapDispose($hBmp)
    _WinAPI_DeleteObject($hBMP_Screen)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    Local $iMetricsSumX = ($bH > $iH ) * $iVSscroll + $iXFixedFrame * 2
    Local $iMetricsSumY = ($bW > $iW) * $iHSscroll + $iYCaption + $iYFixedFrame

    [/autoit] [autoit][/autoit] [autoit]

    $iNewW = Min($bW, $iW)
    $iNewH = Min($bH, $iH)
    Calc_Offset()

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetPos($idPic, $IE_offset_x, $IE_offset_y, $iNewW, $iNewH)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_BitmapDispose($hGfx_IE_BMP_Display)
    _GDIPlus_GraphicsDispose($hCtx_IE_BMP_Display)

    [/autoit] [autoit][/autoit] [autoit]

    $hGfx_IE_BMP_Display = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iNewW, "int", $iNewH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    $hGfx_IE_BMP_Display = $hGfx_IE_BMP_Display[6]
    $hCtx_IE_BMP_Display = _GDIPlus_ImageGetGraphicsContext($hGfx_IE_BMP_Display)
    _GDIPlus_GraphicsSetSmoothingMode($hCtx_IE_BMP_Display, 2)

    [/autoit] [autoit][/autoit] [autoit]

    $IE_ScrollbarV = False
    $IE_ScrollbarH = False

    [/autoit] [autoit][/autoit] [autoit]

    If $bW > $iNewW Or $bH > $iNewW Then
    _GUIScrollBars_Init($hGUI)
    _GUIScrollBars_SetScrollInfoMin($hGUI, $SB_HORZ, 0)
    _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_HORZ, $bW - $iW + 61 + $iMetricsSumX)
    _GUIScrollBars_SetScrollInfoMin($hGUI, $SB_VERT, 0)
    _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, $bH - $iH + $iMetricsSumY - 1)
    GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL_IE")
    GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL_IE")

    [/autoit] [autoit][/autoit] [autoit]

    If $bW > $iW Then
    WM_HSCROLL_IE($hGUI, 0, $SB_THUMBTRACK, 0)
    $IE_ScrollbarH = True
    EndIf
    If $bH > ($iH) Then
    WM_VSCROLL_IE($hGUI, 0, $SB_THUMBTRACK, 0)
    $IE_ScrollbarV = True
    EndIf
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Calc_Offset()
    Local $iDiff_x = $bW - $iW, $iDiff_y = $bH - $iH

    [/autoit] [autoit][/autoit] [autoit]

    If $iDiff_x < 0 Then
    $IE_offset_x = ($iW - $bW) / 2
    $IE_signX = -1
    Else
    $IE_offset_x = 0
    $IE_signX = 1
    EndIf
    $delta_x = ($iW - $iNewW) / 2

    [/autoit] [autoit][/autoit] [autoit]

    If $iDiff_y < 0 Then
    $IE_offset_y = ($iH - $bH) / 2
    $delta_y = ($iH - $iNewH) / 2
    $IE_signY = -1
    Else
    $IE_offset_y = 0
    $delta_y = ($iH - $iNewH) / 2
    $IE_signY = 1
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    Local $tSCROLLINFO_Y = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO_Y, "nMin")
    $Max = DllStructGetData($tSCROLLINFO_Y, "nMax")
    $Page = DllStructGetData($tSCROLLINFO_Y, "nPage")

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImageRectRect($hCtx_IE_BMP_Display, $hBmp, $IE_offset_x * $IE_ScrollbarH, $IE_offset_y * $IE_ScrollbarV, $iNewW, $iNewH, 0, 0, $iNewW, $iNewH)
    CopyImage2Control($idPic, $hGfx_IE_BMP_Display)

    [/autoit] [autoit][/autoit] [autoit]

    Return "GUI_RUNDEFMSG"
    EndFunc ;==>WM_VSCROLL_IE

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    Local $tSCROLLINFO_X = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $Min = DllStructGetData($tSCROLLINFO_X, "nMin")
    $Max = DllStructGetData($tSCROLLINFO_X, "nMax")
    $Page = DllStructGetData($tSCROLLINFO_X, "nPage")

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    $IE_offset_x = DllStructGetData($tSCROLLINFO_X, "nPos")
    _GDIPlus_GraphicsDrawImageRectRect($hCtx_IE_BMP_Display, $hBmp, $IE_offset_x * $IE_ScrollbarH, $IE_offset_y * $IE_ScrollbarV, $iNewW, $iNewH, 0, 0, $iNewW, $iNewH)
    CopyImage2Control($idPic, $hGfx_IE_BMP_Display)

    [/autoit] [autoit][/autoit] [autoit]

    Return "GUI_RUNDEFMSG"
    EndFunc ;==>WM_HSCROLL_IE

    [/autoit] [autoit][/autoit] [autoit]

    Func CopyImage2Control($idControl, $hBmp)
    Local Const $hHBitmap_ImageEditor = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp)
    Local Const $hB = GUICtrlSendMsg($idControl, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap_ImageEditor)
    If $hB Then _WinAPI_DeleteObject($hB)
    _WinAPI_DeleteObject($hHBitmap_ImageEditor)
    EndFunc ;==>CopyImage2Control

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func Min($a, $b)
    If $a < $b Then Return $a
    Return $b
    EndFunc ;==>Min

    [/autoit] [autoit][/autoit] [autoit]

    Func Max($a, $b)
    If $a > $b Then Return $a
    Return $b
    EndFunc ;==>Max

    [/autoit]

    Beispiel ist ein Fast Hack und stammt vom Basic Image Editor v2...

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hallo UEZ,

    vielen Dank ür die Antwort.

    Bei Koda habe ich nun die Styles "WS_HSCROLL" und "WS_VSCROLL" gefunden.

    [autoit]

    $Pic1 = GUICtrlCreatePic("", 48, 24, 65, 137, BitOR($GUI_SS_DEFAULT_PIC,$WS_HSCROLL,$WS_VSCROLL))

    [/autoit]

    Weiß jemand ob und wie das damit funktioniert?
    Zudem möchte ich, wenn ich ein Bild lade, dass dieses in Originalgröße angezeigt wird, aber die Größe des Pic-Steuerlements nicht verändert wird. Wenn man bei Koda bei Pic1 unter "Stretch" "sRealSize" auswählt, wird die Größe der Picturebox auf die Originalgröße des Bildes verändert!Gibt es dort eine Lösung?

    LG K.K.

    • Offizieller Beitrag

    Mit Koda zu arbeiten ist vielleicht für den Anfang hilfreich, aber trotzdem nicht zu empfehlen. Dabei lernst du nichts und hast auch keine reale Vorstellung von den einzelnen Komponenten - also: selber machen.
    Zumal hier kaum jemand Koda nutzt und somit diesbezügliche Fragen kaum eine keine Klärung finden werden.