Что нового

Добавить иконку в ImageList в правильном формате

musicstashall

Знающий
Сообщения
322
Репутация
7
Всем доброго. Имеются следующие функции для рисования иконки при перетаскивании элементов TreeView. Хотел добавить еще одну иконку в лист для рисования ее в запрещенных зонах TreeView.

Код:
Func TreeCreateDragImage($hWnd, $hItem)
    ;if treeview has imagelist, use image from it
    If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then Return _GUICtrlTreeView_CreateDragImage($hWnd, $hItem)
    ;if not, create a bitmap of dragitem's text rectangle and put it into imagelist.
    Local $aItemRect = _GUICtrlTreeView_DisplayRect($hWnd, $hItem, True)
    Local $iImgW = $aItemRect[2]-$aItemRect[0]
    Local $iImgH = $aItemRect[3]-$aItemRect[1]
	Local $hTreeDC = _WinAPI_GetDC($hWnd)
    Local $hMemDC = _WinAPI_CreateCompatibleDC($hTreeDC)
    Local $hMemBmp = _WinAPI_CreateCompatibleBitmap($hTreeDC, $iImgW, $iImgH)
    Local $hMemBmpInvalid = _WinAPI_Create32BitHBITMAP(_WinAPI_ShellExtractIcon(@SystemDir & '\shell32.dll', 131, $iImgW, $iImgH), 1, 1) ; вторая иконка
    Local $hMemBmpOld = _WinAPI_SelectObject($hMemDC, $hMemBmp)
    _WinAPI_BitBlt($hMemDC, 0, 0, $iImgW, $iImgH, $hTreeDC, $aItemRect[0], $aItemRect[1], $SRCCOPY)
    _WinAPI_SelectObject($hMemDC, $hMemBmpOld)
    _WinAPI_ReleaseDC($hWnd, $hTreeDC)
    _WinAPI_DeleteDC($hMemDC)
    Local $hImgList = _GUIImageList_Create($iImgW, $iImgH, 6)
    _GUIImageList_Add($hImgList, $hMemBmp)
    _GUIImageList_Add($hImgList, $hMemBmpInvalid)
    _WinAPI_DeleteObject($hMemBmp)
    _WinAPI_DeleteObject($hMemBmpInvalid)
    Return $hImgList
EndFunc

; Draw drag image
; by Gary Frost (gafrost) (?)
Func DrawDragImage(ByRef $hControl, ByRef $aDrag, $Index = 0)
    Local $tPoint, $hDC
    $hDC = _WinAPI_GetWindowDC($hControl)
    $tPoint = _WinAPI_GetMousePos(True, $hControl)
    _WinAPI_InvalidateRect($hControl)
    _GUIImageList_Draw($aDrag, $Index, $hDC, DllStructGetData($tPoint, "X")-10, DllStructGetData($tPoint, "Y")-8)
    _WinAPI_ReleaseDC($hControl, $hDC)
EndFunc   ;==>DrawDragImage


Добавлять пытаюсь иконку $hMemBmpInvalid. Потом хочу использовать таким образом:

Код:
$hTreeDragImage = TreeCreateDragImage($hTree, $hDragItem)

If $DragIsList And Not $HoverIsList Then ; условие
    DrawDragImage($hTree, $hTreeDragImage, 1) ; рисуется вторая иконка
Else 
    DrawDragImage($hTree, $hTreeDragImage) ; рисуется первая иконка
EndIf


Не рисуется вторая иконка. Помогайте, народ :smile:
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Вот полный пример дерева с иконками. Перетаскиваем элемент и возле курсора рисуется иконка элемента дерева. Я хотел в лист иконок добавить вторую, чтобы рисовать ее, когда элемент перетаскивается в недопустимую зону дерева.

Код:
#include <WinAPIMisc.au3>
#include <GUITreeView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>

Opt("GUICloseOnESC", 0)
Opt("GUIOnEventMode", 1)

$sTitle = "Treeview Drag & Drop Editing"
;Required global constants:
Global $bTreeDrag = False, $bTreeEdit = False, $hDragItem, $hTreeDragImage, $fWhere

$hGui = GUICreate($sTitle, 400, 300, -1, -1, -1, -1)

$label = GUICtrlCreateLabel("Drag and drop separate items or branches to move them." & _
                                    @LF & "To start edit selected item, LMB on item or press Enter." & _
                                    @LF & "To end editing, LMB outside item (apply) or Esc (cancel) / Enter (apply)." & _
                                    @LF & "To insert new item press Insert, to delete existing item press Delete.", 30, 10, 340, 60)

$cTree = GUICtrlCreateTreeView(50,75,300,200,$TVS_HASBUTTONS+$TVS_HASLINES+$TVS_LINESATROOT+$TVS_EDITLABELS+$TVS_CHECKBOXES)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
$cTreeItemsStart = GUICtrlCreateDummy()
$cTreeItem_1 = GUICtrlCreateTreeViewItem("item 1", $cTree)
$cTreeItem_1a = GUICtrlCreateTreeViewItem("item 1a", $cTreeItem_1)
$cTreeItem_1b = GUICtrlCreateTreeViewItem("item 1b", $cTreeItem_1)
$cTreeItem_2 = GUICtrlCreateTreeViewItem("item 2", $cTree)
$cTreeItem_2a = GUICtrlCreateTreeViewItem("item 2a", $cTreeItem_2)
$cTreeItem_3 = GUICtrlCreateTreeViewItem("item 3", $cTree)
$cTreeItem_3a = GUICtrlCreateTreeViewItem("item 3a", $cTreeItem_3)
$cTreeItem_3a1 = GUICtrlCreateTreeViewItem("item 3a1", $cTreeItem_3a)
$cTreeItem_4 = GUICtrlCreateTreeViewItem("item 4", $cTree)
$cTreeItemsEnd = GUICtrlCreateDummy()
;treeview with images test:
$hImgList = _GUIImageList_Create (16, 16)
For $ii = 1 To $cTreeItemsEnd-$cTreeItemsStart
   _GUIImageList_AddIcon ($hImgList, "shell32.dll", 60+$ii*2)
Next
_GUICtrlTreeView_SetNormalImageList(GUICtrlGetHandle($cTree), $hImgList)
$a = 0
For $i = $cTreeItemsStart+1 To $cTreeItemsEnd-1
   _GUICtrlTreeView_SetImageIndex($cTree, _GUICtrlTreeView_GetItemHandle($cTree, $i), $a)
   _GUICtrlTreeView_SetSelectedImageIndex($cTree, _GUICtrlTreeView_GetItemHandle($cTree, $i), $a)
   $a += 1
Next

$label2 = GUICtrlCreateLabel("", 50, 280, 300, 15)

GUISetOnEvent($GUI_EVENT_CLOSE, "SysEvents")
GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SysEvents")
GUISetOnEvent($GUI_EVENT_PRIMARYUP, "SysEvents")
GUIRegisterMsg($WM_NOTIFY, "On_WM_NOTIFY")

GUISetState()

While 1
      Sleep(200)
      ;add Enter, Esc, Delete and Insert key functionality to treeview edit:
      TreeKeyboardFunc($cTree)
WEnd

Func SysEvents()
      Local $hTree = GUICtrlGetHandle($cTree)
      Switch @GUI_CtrlId
            Case $GUI_EVENT_CLOSE
                  Exit
            Case $GUI_EVENT_PRIMARYUP
                  If $bTreeDrag Then
                        _WinAPI_InvalidateRect($hTree)
                        $bTreeDrag = False
                        _GUIImageList_Destroy($hTreeDragImage) ;delete drag image
                        _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget
                        _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark
                        If (TreeItemFromPoint($hTree) = $hDragItem) Then ContinueCase
                        ;move item:
                        $hItem = TreeItemCopy($hTree, $hDragItem, TreeItemFromPoint($hTree), $fWhere)
                        If $hItem <> 0 Then
                              _GUICtrlTreeView_SelectItem($hTree, $hItem)
                              _SendMessage($hTree, $TVM_DELETEITEM, 0, $hDragItem, 0, "wparam", "handle", "hwnd")
                        EndIf
                  EndIf
            Case $GUI_EVENT_MOUSEMOVE
                  If $bTreeDrag = False Then ContinueCase
                  $tPos = _WinAPI_GetMousePos()
                  $Hwnd = _WinAPI_WindowFromPoint($tPos)
                  ;cancel drag in progress and cleanup if moved outside treeview:
                  If ($Hwnd <> $hTree) Then
                        $bTreeDrag = False
                        _WinAPI_InvalidateRect($hTree)
                        _GUIImageList_Destroy($hTreeDragImage) ;delete drag image
                        _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget
                        _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark
                        ContinueCase
                  EndIf
                  $hItemHover = TreeItemFromPoint($hTree)
                  If $hItemHover = 0 Then
                        ;meh
                  Else
                        $aRect = __GUICtrlTreeView_DisplayRect($hTree, $hItemHover)
                        $iTreeY = _WinAPI_GetMousePosY(True, $hTree)
                        Switch $iTreeY
                              Case $aRect[1] To $aRect[1]+Int(($aRect[3]-$aRect[1])/4)
                                    _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget
                                    _SendMessage($hTree, $TVM_SETINSERTMARK, 0, $hItemHover) ;add InsertMark before item
                                    $fWhere = -1
                              Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])/3) To $aRect[1]+Int(($aRect[3]-$aRect[1])*2/3)
                                    _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark
                                    _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) ;add DropTarget
                                    $fWhere = 0
                              Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) To $aRect[3]
                                    _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget
                                    _SendMessage($hTree, $TVM_SETINSERTMARK, 1, $hItemHover) ;add InsertMark after item
                                    $fWhere = 1
                        EndSwitch
                  EndIf
                  DrawDragImage($hTree, $hTreeDragImage)
      EndSwitch
EndFunc
;    TreeItemFromPoint()
;    Returns handle of tree item under mouse:

Func TreeItemFromPoint($hWnd)
      Local $tMPos = _WinAPI_GetMousePos(True, $hWnd)
      Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
EndFunc
;    TreeItemCopy()
;    Copies tree item $hItemSource and all its children to an item $hItemTarget, depending on $fDirection
;    $fDirection:
;                -1 = before $hItemTarget
;                0 = inside $hItemTarget
;                1 = after $hItemTarget

Func TreeItemCopy($hWnd, $hItemSource, $hItemTarget, $fDirection)
      ;making sure parent can't be dropped onto one of its descendants:
      $hTest = $hItemTarget
      Do
            $hTest = _GUICtrlTreeView_GetParentHandle($hWnd, $hTest)
            If $hTest = $hItemSource Then Return 0
      Until $hTest = 0
      ;create new item at determined position
      $sText = _GUICtrlTreeView_GetText($hWnd, $hItemSource)
      $hParent = _GUICtrlTreeView_GetParentHandle($hWnd, $hItemTarget)
      Switch $fDirection
            Case -1
                  $hPrev = _GUICtrlTreeView_GetPrevSibling($hWnd, $hItemTarget)
                  If $hPrev = 0 Then
                        $hNew = _GUICtrlTreeView_AddFirst($hWnd, $hItemTarget, $sText)
                  Else
                        $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hPrev)
                  EndIf
            Case 0
                  $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hItemTarget)
            Case 1
                  $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hItemTarget)
            Case Else
                  Return 0
      EndSwitch
      ;save item state and checkbox image if there is such
      _GUICtrlTreeView_SetState($hWnd, $hNew, _GUICtrlTreeView_GetState($hWnd, $hItemSource))
      If _GUICtrlTreeView_GetStateImageList($hWnd) <> 0 Then
            _GUICtrlTreeView_SetStateImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetStateImageIndex($hWnd, $hItemSource))
      EndIf
      ;save icon/selected image indexes
      If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then
            _GUICtrlTreeView_SetImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetImageIndex($hWnd, $hItemSource))
            _GUICtrlTreeView_SetSelectedImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetSelectedImageIndex($hWnd, $hItemSource))
      EndIf
      ;recurse through descendants:
      $iChildCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItemSource)
      If $iChildCount > 0 Then
            For $i = 0 To $iChildCount-1
                  $hRecSource = _GUICtrlTreeView_GetItemByIndex($hWnd, $hItemSource, $i)
                  TreeItemCopy($hWnd, $hRecSource, $hNew, 0)
            Next
      EndIf
      Return $hNew
EndFunc

Func On_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
      ;wparam = cid, lparam = pnmh
      If $wParam = $cTree Then
            Local $tNMHDR = DllStructCreate("hwnd hTree;uint_ptr;int code", $lParam)
            Local $code = DllStructGetData($tNMHDR, "code")
            Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree"))
            Switch $code
                  Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW
                        $bTreeDrag = True
                        $hDragItem = TreeItemFromPoint($hTree)
;~                     _GUICtrlTreeView_SelectItem($hTree, $hDragItem)
                        _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False)
                        $hTreeDragImage = TreeCreateDragImage($hTree, $hDragItem)
                        DrawDragImage($hTree, $hTreeDragImage)
                  Case $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW
                        $bTreeEdit = True
;~                     $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0)
                  Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW
                        $bTreeEdit = False
                        Return 1
                  Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW
;~                     ;Local $hSel = _GUICtrlTreeView_GetSelection($hTree)
;~                     Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam)
;~                     Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem")
;~                     Local $sTxt = "Currently selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")"
;~                     GUICtrlSetData($label2, $sTxt)
                  Case Else
            EndSwitch
            ;
      EndIf
EndFunc

Func KeyPressed($iHexKey)
      Local $aRet = DllCall('user32.dll', "int", "GetAsyncKeyState", "int", $iHexKey)
;~   If BitAND($aRet[0], 0x8000) Or BitAND($aRet[0], 1) Then Return 1
      If BitAND($aRet[0], 1) Then Return 1
      Return 0
EndFunc

Func TreeKeyboardFunc($cID)
      Local $hWnd = GUICtrlGetHandle($cID)
      If $bTreeDrag Then Return
      If $bTreeEdit Then
            If KeyPressed(0x0d) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 0, 0) ;enter
            If KeyPressed(0x1b) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 1, 0) ;esc
      EndIf
      Local $aRet = DllCall('user32.dll', 'hwnd', 'GetFocus')
      If $aRet[0] = $hWnd Then
            If KeyPressed(0x2d) Then _GUICtrlTreeView_Add($hWnd, _GUICtrlTreeView_GetSelection($hWnd), "New Item") ;insert
            If KeyPressed(0x2e) Then _GUICtrlTreeView_Delete($hWnd, _GUICtrlTreeView_GetSelection($hWnd)) ;delete
            If KeyPressed(0x0d) Then _SendMessage($hWnd, $TVM_EDITLABELA, 0, _GUICtrlTreeView_GetSelection($hWnd)) ;enter
      EndIf
EndFunc

Func TreeCreateDragImage($hWnd, $hItem)
      ;if treeview has imagelist, use image from it
      If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then Return _GUICtrlTreeView_CreateDragImage($hWnd, $hItem)
      ;if not, create a bitmap of dragitem's text rectangle and put it into imagelist.
      Local $aItemRect = __GUICtrlTreeView_DisplayRect($hWnd, $hItem, True)
      Local $iImgW = $aItemRect[2]-$aItemRect[0]
      Local $iImgH = $aItemRect[3]-$aItemRect[1]
      Local $hTreeDC = _WinAPI_GetDC($hWnd)
      Local $hMemDC = _WinAPI_CreateCompatibleDC($hTreeDC)
      Local $hMemBmp = _WinAPI_CreateCompatibleBitmap($hTreeDC, $iImgW, $iImgH)
      Local $hMemBmpOld = _WinAPI_SelectObject($hMemDC, $hMemBmp)
      _WinAPI_BitBlt($hMemDC, 0, 0, $iImgW, $iImgH, $hTreeDC, $aItemRect[0], $aItemRect[1], $SRCCOPY)
      _WinAPI_SelectObject($hMemDC, $hMemBmpOld)
      _WinAPI_ReleaseDC($hWnd, $hTreeDC)
      _WinAPI_DeleteDC($hMemDC)
      Local $hImgList = _GUIImageList_Create($iImgW, $iImgH, 6)
      _GUIImageList_Add($hImgList, $hMemBmp)
      _WinAPI_DeleteObject($hMemBmp)
      Return $hImgList
EndFunc

; Draw drag image
; by Gary Frost (gafrost) (?)
Func DrawDragImage(ByRef $hControl, ByRef $aDrag)
      Local $tPoint, $hDC
      $hDC = _WinAPI_GetWindowDC($hControl)
      $tPoint = _WinAPI_GetMousePos(True, $hControl)
      _WinAPI_InvalidateRect($hControl)
      _GUIImageList_Draw($aDrag, 0, $hDC, DllStructGetData($tPoint, "X")-10, DllStructGetData($tPoint, "Y")-8)
      _WinAPI_ReleaseDC($hControl, $hDC)
EndFunc    ;==>DrawDragImage

Func __GUICtrlTreeView_DisplayRect($hWnd, $hItem, $bTextOnly = False)
      Local $tRECT = DllStructCreate("int_ptr Left;int_ptr Top;int_ptr Right;int_ptr Bottom")
      DllStructSetData($tRECT, "Left", $hItem)
      _SendMessage($hWnd, $TVM_GETITEMRECT, $bTextOnly, $tRECT, 0, "wparam", "struct*")
      Local $aRect[4]
      $aRect[0] = DllStructGetData($tRECT, "Left")
      $aRect[1] = DllStructGetData($tRECT, "Top")
      $aRect[2] = DllStructGetData($tRECT, "Right")
      $aRect[3] = DllStructGetData($tRECT, "Bottom")
      If @AutoItX64 Then
        Local $aRect_ = $aRect
        $aRect[0] = _WinAPI_LoDWord($aRect_[0])
        $aRect[1] = _WinAPI_HiDWord($aRect_[0])
        $aRect[2] = _WinAPI_LoDWord($aRect_[1])
        $aRect[3] = _WinAPI_HiDWord($aRect_[1])
      EndIf
      Return $aRect
EndFunc   ;==>__GUICtrlTreeView_DisplayRect
 
Верх