Что нового

[Элементы GUI] Присвоение контекстного меню элементам окна

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Здравствуйте, просьба помочь в присвоении контекстного меню к такому элементу окна как Rich Edit, у меня есть не большие наброски. Но к сожалению данный метод не работает для Rich элемента, хотя например для окна или стандартной кнопке такое работает:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiRichEdit.au3>
#include <GuiMenu.au3>
OnAutoItExitRegister("_Quit")
Global $copymenu
$Form1 = GUICreate("Rich - Edit", 411, 371, 275, 159)
$Edit1 = _GUICtrlRichEdit_Create($Form1,"", 0, 0, 201, 369,BitOR($WS_HSCROLL,$ES_AUTOVSCROLL,$ES_MULTILINE,$WS_VSCROLL))
$Edit2 = _GUICtrlRichEdit_Create($Form1,"", 208, 0, 201, 369,BitOR($WS_HSCROLL,$ES_AUTOVSCROLL,$ES_MULTILINE,$WS_VSCROLL))
$menu1=GUICtrlCreateContextMenu($Edit1)
$menu2=GUICtrlCreateContextMenu($Edit2)
GUIRegisterMsg($wm_contextmenu,"__ContextMenu")
GUIRegisterMsg($wm_command,"__commandmenu")
GUISetState(@SW_SHOW)
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit

	EndSwitch
WEnd
Func __commandmenu($win,$msg,$wparam,$lparam)
	Switch $wparam
		Case $copymenu
			MsgBox(0,'','copy')
	EndSwitch
EndFunc
Func __ContextMenu($win,$msg,$wparam,$lparam)
	Switch $wparam
		Case $Edit1;Для $Form1 данный метод работает
			Local $menu=_GUICtrlMenu_CreatePopup()
			_GUICtrlMenu_InsertMenuItem($menu,0,"Копировать",$copymenu)
			_GUICtrlMenu_TrackPopupMenu($menu,$wparam)
			_GUICtrlMenu_DestroyMenu($menu)
	EndSwitch
	Return True
EndFunc
Func _Quit()
	_GUICtrlRichEdit_Destroy($Edit1)
	_GUICtrlRichEdit_Destroy($Edit2)
EndFunc
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
MnM
Сделай обработчик на нажатие. И в условие твой RichEdit.
Для создания контекстного меню по координатам клика используй библиотеку:
Код:
#Include <GUIMenu.au3>

_GUICtrlMenu_CreatePopup
_GUICtrlMenu_TrackPopupMenu


Вот вырезка из моего старого проекта:
Код:
$hMenu[0 ] = _GUICtrlMenu_CreatePopup()
	_GUICtrlMenu_SetMenuStyle($hMenu[0 ], $MNS_DRAGDROP)
	$hMenu[1 ] = _GUICtrlMenu_InsertMenuItem($hMenu[0 ], 0, "Listen to new port (+Listen)", $hMenuID[1])
	_GUICtrlMenu_InsertMenuItem($hMenu[0 ], 1, "", 0)
	$hMenu[2 ] = _GUICtrlMenu_InsertMenuItem($hMenu[0 ], 2, "Client settings", $hMenuID[2])
	$hMenu[3 ] = _GUICtrlMenu_InsertMenuItem($hMenu[0 ], 3, "", $hMenuID[3])
	_GUICtrlMenu_InsertMenuItem($hMenu[0 ], 4, "", 0)
	$hMenu[4 ] = _GUICtrlMenu_InsertMenuItem($hMenu[0 ], 5, "", $hMenuID[4])
	$hMenu[5 ] = _GUICtrlMenu_InsertMenuItem($hMenu[0 ], 6, "", $hMenuID[5])
	_GUICtrlMenu_InsertMenuItem($hMenu[0 ], 7, "", 0)
	$hMenu[6 ] = _GUICtrlMenu_InsertMenuItem($hMenu[0 ], 8, "", $hMenuID[6])
	$hMenu[7 ] = _GUICtrlMenu_InsertMenuItem($hMenu[0 ], 9, "A problem? Show help", $hMenuID[7])
	$hMenu[8 ] = _GUICtrlMenu_InsertMenuItem($hMenu[0 ], 10, "Exit the software", $hMenuID[8])

	$hImageList = _GUIImageList_Create(14, 14, 6, 1)
	For $Index = 201 To 208
		_GUIImageList_AddIcon($hImageList, @ScriptDir & '\Resources\' & $Index & '.ico')
	Next

	_GUICtrlMenu_SetItemBmp($hMenu[0 ], 0, _GUIImageList_GetBmp( $hImageList, 0 ) )
	_GUICtrlMenu_SetItemBmp($hMenu[0 ], 2, _GUIImageList_GetBmp( $hImageList, 1 ) )
	_GUICtrlMenu_SetItemBmp($hMenu[0 ], 3, _GUIImageList_GetBmp( $hImageList, 2 ) )
	_GUICtrlMenu_SetItemBmp($hMenu[0 ], 5, _GUIImageList_GetBmp( $hImageList, 3 ) )
	_GUICtrlMenu_SetItemBmp($hMenu[0 ], 6, _GUIImageList_GetBmp( $hImageList, 4 ) )
	_GUICtrlMenu_SetItemBmp($hMenu[0 ], 8, _GUIImageList_GetBmp( $hImageList, 5 ) )
	_GUICtrlMenu_SetItemBmp($hMenu[0 ], 9, _GUIImageList_GetBmp( $hImageList, 6 ) )
	_GUICtrlMenu_SetItemBmp($hMenu[0 ], 10, _GUIImageList_GetBmp( $hImageList, 7 ) )

	$Index = _GUICtrlMenu_TrackPopupMenu($hMenu[0 ], $hGUI, $gPos[0]+16, $gPos[1]+50, 1, 1, 2)
 
Автор
MnM

MnM

Post-Hardcore
Сообщения
679
Репутация
90
firex, зачем вы мне даете те кусочки кода которые у меня уже есть.
firex сказал(а):
Сделай обработчик на нажатие. И в условие твой RichEdit.
Я сделал через wm_command но как-то не получается/


Добавлено:
Сообщение автоматически объединено:

дело в том что RichEdit возвращает при создании дескриптор свой, а не ид. По id может быть легче было бы. По координатам тоже идея, но придется массив с циклом делать не хиленький оборот по всему элементу.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
MnM
Ты меня кажется не понял.
Тебе нужно отловить клик, получить его координаты и нарисовать выпадающее меню.

Лично у меня оно создавалось заново после каждого клика.
 
Автор
MnM

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Мне бы помог больше пример, если тебе не трудно=)


Добавлено:
Сообщение автоматически объединено:

Нашел решение через применение функции $wm_setcursor
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiRichEdit.au3>
#include <GuiMenu.au3>
OnAutoItExitRegister("_Quit")
Global $copymenu,$itemhan
$Form1 = GUICreate("Rich - Edit", 411, 371, 275, 159)
$Edit1 = _GUICtrlRichEdit_Create($Form1,"", 0, 0, 201, 369,BitOR($WS_HSCROLL,$ES_AUTOVSCROLL,$ES_MULTILINE,$WS_VSCROLL))
$Edit2 = _GUICtrlRichEdit_Create($Form1,"", 208, 0, 201, 369,BitOR($WS_HSCROLL,$ES_AUTOVSCROLL,$ES_MULTILINE,$WS_VSCROLL))
$menu1=GUICtrlCreateContextMenu($Edit1)
$menu2=GUICtrlCreateContextMenu($Edit2)
GUIRegisterMsg($wm_notify,"__commandmenu")
GUIRegisterMsg($wm_setcursor,"cursor")
GUISetState(@SW_SHOW)
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit

	EndSwitch
WEnd
Func cursor($win,$msg,$wparam,$lparam)
	Local $s=BitShift($lParam, 16)
	Switch $wparam
		Case $Edit1
			If $s=516 Then
				Local $menu=_GUICtrlMenu_CreatePopup()
				_GUICtrlMenu_InsertMenuItem($menu,0,"Копировать",$copymenu)
				_GUICtrlMenu_TrackPopupMenu($menu,$wparam)
				_GUICtrlMenu_DestroyMenu($menu)
			EndIf
	EndSwitch
EndFunc
Func __commandmenu($win,$msg,$wparam,$lparam)
	Switch $wparam
		Case $copymenu
			MsgBox(0,'','')
	EndSwitch
EndFunc
Func _Quit()
	_GUICtrlRichEdit_Destroy($Edit1)
	_GUICtrlRichEdit_Destroy($Edit2)
EndFunc

Переменная $s примет значение 516 при правом клике по элементу, 513 при левом, 519 при нажатии колесиком, и 512 при наведении :smile:


Добавлено:
Сообщение автоматически объединено:

Немного неувязочка конечно с командой назначения пункту меню, но часть дела сделана=)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
MnM [?]
нету только для элемента RichEdit
А какая разница для чего, пунктам меню назначаются действия независимо.
 
Автор
MnM

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Ну вот смотрите
Код:
#include <GuiMenu.au3>
#include <GuiConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <guirichedit.au3>
Opt('MustDeclareVars', 1)
Global Enum $idOpen = 1000, $idSave, $idInfo
Global $Edit1,$Edit2
_Main()
Func _Main()
    Local $hGUI
    $hGUI = GUICreate("Menu", 400, 300)
	$Edit1 = GUICtrlCreateButton("",0,0,100,20)
	$Edit2 = _GUICtrlRichEdit_Create($hGUI,"", 208, 0, 201, 369,BitOR($WS_HSCROLL,$ES_AUTOVSCROLL,$ES_MULTILINE,$WS_VSCROLL))
    GUISetState()
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    Switch $iwParam
        Case $idOpen
            _WinAPI_ShowMsg ("Open")
        Case $idSave
            _WinAPI_ShowMsg ("Save")
        Case $idInfo
            _WinAPI_ShowMsg ("Info")
    EndSwitch
EndFunc
Func WM_CONTEXTMENU($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hMenu
    $hMenu = _GUICtrlMenu_CreatePopup ()
    _GUICtrlMenu_InsertMenuItem ($hMenu, 0, "Open", $idOpen)
    _GUICtrlMenu_InsertMenuItem ($hMenu, 1, "Save", $idSave)
    _GUICtrlMenu_InsertMenuItem ($hMenu, 3, "", 0)
    _GUICtrlMenu_InsertMenuItem ($hMenu, 3, "Info", $idInfo)
    _GUICtrlMenu_TrackPopupMenu ($hMenu, $iwParam)
    _GUICtrlMenu_DestroyMenu ($hMenu)
    Return True
EndFunc

По сути тут даже без условия появляется меню. В окне 2 элемента, при клике на окно или на кнопку(правой клавишей) выскакивает меню, а при том же нажатии на RicEdit меню не выскакивает!
Пример переделанный из справки данной CreatoR.
 

AZJIO

Меценат
Меценат
Сообщения
2,894
Репутация
1,196
Код:
; Пример меню для элементов, которые не имеют стандартного способа назначения контекстного меню
#include <GuiRichEdit.au3>
#include <GuiMenu.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>

_Main()

Func _Main()
	Local $hGUI, $hMenu, $hRichEdit, $iContMenu, $iMenuItem1, $iMenuItem2
	$hGUI = GUICreate("Меню для RichEdit", 300, 220)
	$hRichEdit = _GUICtrlRichEdit_Create($hGUI, "", 10, 10, 200, 200, BitOR($WS_HSCROLL, $ES_AUTOVSCROLL, $ES_MULTILINE, $WS_VSCROLL))
	GUISetState()

	; Создаёт контекстное меню для пустышки
	$iContMenu = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
	$hMenu = GUICtrlGetHandle($iContMenu)
	$iMenuItem1 = GUICtrlCreateMenuItem('Пункт 1', $iContMenu)
	$iMenuItem2 = GUICtrlCreateMenuItem('Пункт 2', $iContMenu)

	While 1
		Switch GUIGetMsg()
			Case $GUI_EVENT_SECONDARYUP
				_ShowMenu($hGUI, $hMenu, $hRichEdit)
			Case $iMenuItem1
				MsgBox(0, 'Сообщение', 'Событие 1')
			Case $iMenuItem2
				MsgBox(0, 'Сообщение', 'Событие 2')
			Case $GUI_EVENT_CLOSE
				_GUICtrlRichEdit_Destroy($hRichEdit)
				GUIDelete()
				ExitLoop
		EndSwitch
	WEnd
EndFunc   ;==>_Main

Func _ShowMenu($hGUI, $hMenu, $hControl)
	Local $hWnd, $tPoint, $x, $y
	$x = MouseGetPos(0)
	$y = MouseGetPos(1)
	$tPoint = DllStructCreate($tagPoint)
	DllStructSetData($tPoint, "x", $x)
	DllStructSetData($tPoint, "y", $y)
	$hWnd = _WinAPI_WindowFromPoint($tPoint)
	If Not @error And $hWnd = $hControl Then
		; DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hGUI, "ptr", 0)
		_GUICtrlMenu_TrackPopupMenu($hMenu, $hGUI, $x, $y, 1)
	EndIf
EndFunc   ;==>_ShowMenu
 
Автор
MnM

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Снова здравствуйте,
AZJIO вы подали прекрасный пример, но увы такое не происходит почему то при установлении своего курсора =(
Может из-за того что $wm_setcursor срабатывает раньше и подменивая курсор не выскакивает меню?


Добавлено:
Сообщение автоматически объединено:

"Вылечил" таким методом:
Код:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Run_After=ResHacker.exe -add %out%, %out%, work.cur, 12, 100,
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiRichEdit.au3>
#include <GuiMenu.au3>
#include <WinAPIEx.au3>
$in=_WinAPI_GetModuleHandle(0)
$cur=_WinAPI_LoadCursor($in,100)
OnAutoItExitRegister("_Quit")
$Form1 = GUICreate("Rich - Edit", 411, 371, 275, 159)
$Edit1 = _GUICtrlRichEdit_Create($Form1,"", 0, 0, 201, 369,BitOR($WS_HSCROLL,$ES_AUTOVSCROLL,$ES_MULTILINE,$WS_VSCROLL))
$Edit2 = _GUICtrlRichEdit_Create($Form1,"", 208, 0, 201, 369,BitOR($WS_HSCROLL,$ES_AUTOVSCROLL,$ES_MULTILINE,$WS_VSCROLL))
$menu1=GUICtrlCreateContextMenu(GUICtrlCreateDummy())
$hmenu=GUICtrlGetHandle(-1)
$copymenu=GUICtrlCreateMenuItem("Меню",$menu1)
GUIRegisterMsg($wm_setcursor,"cursor")
GUISetState(@SW_SHOW)
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
		Case $copymenu
			MsgBox(0,'',"YES!!!")
    EndSwitch
WEnd
Func cursor($win,$msg,$wparam,$lparam)
    Local $s=BitShift($lParam, 16)
    Switch $wparam
		Case $Edit1
            If $s=516 Then
				$pos=MouseGetPos()
                _GUICtrlMenu_TrackPopupMenu($hmenu,$Form1,$pos[0],$pos[1],1)
				_WinAPI_SetCursor($cur)
				Return 1
			Else
				_WinAPI_SetCursor($cur)
				Return 1
            EndIf
    EndSwitch
EndFunc
Func _Quit()
    _GUICtrlRichEdit_Destroy($Edit1)
    _GUICtrlRichEdit_Destroy($Edit2)
EndFunc

Смесь вашего и моего скрипта :laugh:
 
Верх