Что нового

Как добавить иконки в контекстное меню

pvnn

Осваивающий
Сообщения
305
Репутация
32
Как можно добавить иконки слева от надписей в контекстном меню?
Или средствами autoit это нельзя сделать?

Например вот такой код:
Код:
#include <GUIConstantsEx.au3>
#include <GUIMenu.au3>
#include <GUIListView.au3>
#include <WindowsConstants.au3>
;

Global $hListView , $iLast_LV_Index, $Form1

$Form1 = GUICreate("Context Menu on ListView Items - Example", 400, 300)

$DummyMenu = GUICtrlCreateDummy()
$ContextMenu = GUICtrlCreateContextMenu($DummyMenu)
$Some_Copy = GUICtrlCreateMenuItem("Copy", $ContextMenu)
$Some_Del = GUICtrlCreateMenuItem("Del", $ContextMenu)
$Exit_Item = GUICtrlCreateMenuItem("Exit", $ContextMenu)

$hListView = _GUICtrlListView_Create($Form1, "", 32, 16, 340, 260) ; LEFT],[TOP],WIDTH],[HEIGHT]
_GUICtrlListView_SetExtendedListViewStyle($hListView, _
    BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_CHECKBOXES))

; Add columns
_GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 100)

; Add items
_GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0)
_GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1)
_GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2)

GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    $nMsg = GUIGetMsg()

    Switch $nMsg
        Case $GUI_EVENT_CLOSE,$Exit_Item
            Exit
        Case $Some_Copy
			MsgBox(0,'','Копирование')
        Case $Some_Del
			MsgBox(0,'','Удаление')
    EndSwitch
WEnd

; Show a menu in a given GUI window which belongs to a given GUI ctrl
Func ShowMenu($hWnd, $nContextID, $nContextControlID, $iMouse=0)
    Local $hMenu = GUICtrlGetHandle($nContextID)
    Local $iCtrlPos = ControlGetPos($hWnd, "", $nContextControlID)

    Local $X = $iCtrlPos[0]
    Local $Y = $iCtrlPos[1] + $iCtrlPos[3]

    ClientToScreen($hWnd, $X, $Y)

    If $iMouse Then
        $X = MouseGetPos(0)
        $Y = MouseGetPos(1)
    EndIf

    DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $X, "int", $Y, "hwnd", $hWnd, "ptr", 0)
EndFunc

; Convert the client (GUI) coordinates to screen (desktop) coordinates
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
    Local $stPoint = DllStructCreate("int;int")

    DllStructSetData($stPoint, 1, $x)
    DllStructSetData($stPoint, 2, $y)

    DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))

    $x = DllStructGetData($stPoint, 1)
    $y = DllStructGetData($stPoint, 2)
    ; release Struct not really needed as it is a local
    $stPoint = 0
EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom,  $iCode, $tNMHDR, $hWndListView, $tInfo

    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    $iIndex = DllStructGetData($tInfo, "Index")

                    If $iIndex <> -1 Then
                        $iLast_LV_Index = $iIndex
                        ShowMenu($hWnd, $ContextMenu, $hListView, 1)
                    EndIf
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc
 

Mur

Осваивающий
Сообщения
132
Репутация
32
Можно добавить через реестр, вот тут сказано что и как делать, что за что отвечает. Средствами Autoit можно проделать тоже самое.

Посмотри в примере
Грешу на свой браузер и интернет, когда открыл тему перед ответом - не загрузило ваш исходный код... :'(
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
Mur у меня не системное контекстное меню, а свое!
Посмотри в примере
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
AZJIO Видел эту классую вещь, там контекстное меню прикручено к GUI
Не разобрался как его прикрутить к ListView.
МОжно пример, если не сложно
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Код:
; Пример подготовил AZJIO
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <ModernMenuRaw.au3>

Opt("GUIResizeMode", 802) ; не перемещать элементы

; En
$LngTitle = 'Context menu, ListView'
$LngPath = 'Text'
$LngInd = 'Index'
$LngDel = 'Delete'
$LngItm = 'Item'

; Ru
; если русская локализация, то русский язык
If @OSLang = 0419 Then
	$LngTitle = 'Контекстное меню ListView'
	$LngPath = 'Текст пункта'
	$LngInd = 'Индекс'
	$LngDel = 'Удалить'
	$LngItm = 'Пункт'
EndIf

$hGui = GUICreate($LngTitle, 350, 375, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_OVERLAPPEDWINDOW, $WS_CLIPCHILDREN))

$iListView = GUICtrlCreateListView('Name|Command|Name Menu', 5, 5, 340, 350, -1, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT, $LVS_EX_INFOTIP, $WS_EX_CLIENTEDGE))
GUICtrlSetResizing(-1, 7 + 32 + 64)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
$hListView = GUICtrlGetHandle(-1)
GUICtrlSendMsg($iListView, $LVM_SETCOLUMNWIDTH, 0, 100)
GUICtrlSendMsg($iListView, $LVM_SETCOLUMNWIDTH, 1, 115)
GUICtrlSendMsg($iListView, $LVM_SETCOLUMNWIDTH, 2, 100)

; Создаём пункты
For $i = 0 To 10
	GUICtrlCreateListViewItem($LngItm & ' ' & $i, $iListView)
Next

$iDummy = GUICtrlCreateDummy()

$ContMenu = GUICtrlCreateContextMenu($iDummy)
$hMenu = GUICtrlGetHandle($ContMenu)
$iCM_Path	= _GUICtrlCreateODMenuItem($LngPath & @TAB & 'Enter', $ContMenu, "shell32.dll", -71)
$iCM_Ind	= _GUICtrlCreateODMenuItem($LngInd & @TAB & 'Ctrl+Enter', $ContMenu, "shell32.dll", -24)
$iCM_Del	= _GUICtrlCreateODMenuItem($LngDel & @TAB & 'Ctrl+Del', $ContMenu, "shell32.dll", -132)

Dim $AccelKeys[3][2] = [["{Enter}", $iDummy],["^{DEL}", $iCM_Del],["^{Enter}", $iCM_Ind]] ; установка горячих клавиш на пункты контекстного меню
GUISetAccelerators($AccelKeys)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState()
While 1
	Switch GUIGetMsg()
		Case $iCM_Path
			_OpenExplorer()
		Case $iCM_Del
			$iIndex = ControlListView($hGui, '', 'SysListView321', 'GetSelected')
			If _GUICtrlListView_GetItemSelected($hListView, $iIndex) Then _GUICtrlListView_DeleteItem($hListView, $iIndex)
		Case $iCM_Ind
			MsgBox(0, 'Сообщение', ControlListView($hGui, '', 'SysListView321', 'GetSelected'), 0, $hGui)
		Case $iDummy ; Событие по кнопке Enter, и действие взависимости от того, какой элемент в фокусе
			; MsgBox(0, '', ControlGetFocus($hGui), 0, $hGui)
			Switch ControlGetFocus($hGui)
				; Case 'Edit1'
				; _Read()
				; Case 'Edit4', 'Edit2', 'Edit3'
				; _Add()
				Case 'SysListView321'
					_OpenExplorer()
					; Case 'SysTreeView321'
					; _OpenExplorer()
			EndSwitch
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd

Func _OpenExplorer()
	$ind = ControlListView($hGui, '', 'SysListView321', 'GetSelected')
	MsgBox(0, 'Сообщение', ControlListView($hGui, '', 'SysListView321', 'GetText', $ind), 0, $hGui)
EndFunc   ;==>_OpenExplorer

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
	Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo

	$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
	$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
	$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
	$iCode = DllStructGetData($tNMHDR, "Code")
	Switch $hWndFrom
		Case $hListView
			Switch $iCode
				Case $NM_DBLCLK ; левый двойной клик мышкой по пункту
					_OpenExplorer()

				Case $NM_RCLICK ; правый клик мышкой по пункту
					$tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
					Local $aSel = DllStructGetData($tInfo, "Index")
					If $aSel <> -1 Then
						$x = MouseGetPos(0)
						$y = MouseGetPos(1)
						DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hGui, "ptr", 0)
					EndIf
			EndSwitch
	EndSwitch

	$tNMHDR = 0
	$tInfo = 0
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 
Автор
P

pvnn

Осваивающий
Сообщения
305
Репутация
32
AZJIO Спасибо Большое за пример. Как раз то что надо!
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
оно уже давно есть в справке. но только рассчитано на 32-битную систему.
в теме, указанной CreatoR -ом как раз есть исправленный вариант для совместимости с х64
думаю, что в справке тоже нужно этот вариант применить
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
CreatoR
Может официально на форуме предложить Holger обновить UDF? Я сейчас добавил в справку ещё 10 функций из этой библиотеки и удивился, что 3-ий параметр устанавливающий порядковый номер пункта игнорируется, а ведь в его же примере "Recent Files" как раз надо добавлять в начало списка и позиция имеет значение.
 
Верх