Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Контекстное меню [D5, Win95/98, NT4, Win2k, WinXP]


Андрю-ХА ©   (2004-01-13 12:08:00) 

Как доступиться к стандартному контекстному меню TMemo для его модификации?


esVer   (2004-01-14 12:58:00) [1]

Я пробовал ниже приведенный код, но он у меня не прошел, к сожалению. Глючил иногда, пришлось отказаться.


//Add items to standard context menu. v 2.1.
//(c) Eugene Korolev  korolev'собака'soft4you'точка'com, 1999

// Этот модуль предназначен для добавления к стандартному popupmenu control'а
//windows - 'Edit'а дополнительных пунктов. При желании легко переделывается
//в глобальный хук для всех приложений. Главное - идея.
//Модуль может распространяться и модифицироваться свободно только при
//сохранении копирайта. Запрещается создание non-freeware компанент на
//основе идей, взятых из этого кода.

unit ApiPopUp;

interface
uses Windows, Messages;

type
 
 TRunPopUpitem = procedure (Wnd: HWND; Menu: DWORD; MenuItem: DWORD); stdcall;
 
 pPopUpItem = ^TPopUpItem;
 TPopUpItem = record
   uFlags: DWORD;
   uIDNewItem: DWORD;
   lpNewItem: PChar;
   Run: TRunPopUpitem;
 end;

 PPopUp = ^TPopUp;
 TPopUp = array[1..100] of TPopUpItem;
 
procedure AddPopUpMenu(sPopUp: PPopUp; sNumber: DWORD; Wnd: HWND); stdcall;

type
 TwndProc = function (HWND: DWORD; AMessage, WPARAM, LPARAM: DWORD): DWORD; stdcall;
 
implementation

var
 Menu            : DWORD;    
 
 MenuChanged     : Boolean;  
 HookHandle      : DWORD = 0;
 lPopUp          : PPopUp;
 lPopUpNumber    : DWORD;
 OldMenuItemCount: DWORD;
 SaveWnd         : HWND;

function MsgProc(Code: Integer; WPARAM: Integer; LPARAM: PCWPStruct): Integer; stdcall;
 //Function hProc(hwnd:dword;AMessage,Wparam,LParam:dword):dword;stdcall;
var
 Quit: Boolean;
 I   : DWORD;
begin
 Quit := False;
 if (Code = HC_ACTION) then case LPARAM.message of
     $4CC, $1ED:
       if LPARAM.WPARAM > OldMenuItemCount then
       begin
         I := LPARAM.WPARAM - OldMenuItemCount;
         if @lPopUp^[I].Run <> nil then lPopUp^[I].Run(SaveWnd, Menu, LPARAM.WPARAM);
       end;
     WM_MENUSELECT:
       if (DWORD(LPARAM.WPARAM) = $FFFF0000) then Quit := True else if Menu = 0 then
       begin
         Menu := LPARAM.LPARAM;
         OldMenuItemCount := GetMenuItemCount(Menu) - 1;
         for I := 1 to lPopUpNumber do
           with lPopUp^[I] do
             Windows.InsertMenu(Menu, $FFFFFFFF, uFlags, uIDNewItem, lpNewItem);
       end;

     $1E2: if not MenuChanged then
     begin
       MenuChanged := True;
       //Отправим сообщение для возврата ID меню
       SendMessage(LPARAM.HWND, $1E5, 0, 0);
       SendMessage(LPARAM.HWND, $1E5, $FFFFFFFF, 0);
     end;
   end;
 MsgProc := CallNextHookEx(HookHandle, Code, WPARAM, DWORD(LPARAM));
 if Quit then
 begin
   UnhookWindowsHookEx(HookHandle);
   HookHandle := 0;
 end;
end;

procedure AddPopUpMenu(sPopUp: PPopUp; sNumber: DWORD; Wnd: HWND); stdcall;
begin
 SaveWnd := Wnd;
 MenuChanged := False;
 lPopUp := sPopUp;
 lPopUpNumber := sNumber;
 Menu := 0;
 if HookHandle <> 0 then UnhookWindowsHookEx(HookHandle);
 HookHandle := SetWindowsHookEx(WH_CALLWNDPROC, @MsgProc, 0, GetCurrentThreadId);
end;

end.
 
 {Пример использования:
 procedure AddEditPopUpClearAll(wnd:hwnd;Menu:dword;MenuItem:dword);stdcall;
 begin
 SetWindowText(wnd,'');
 end;
 
 const
  AddEditPopUp:array[1..1] of TPopUpItem=(
    (uFlags:MF_STRING or MF_ENABLED or MF_UNCHECKED or MF_BYPOSITION;
      uIDNewItem:$4396;
      lpNewItem:'ClearAll';
      Run:AddEditPopUpClearAll));
 ...
 case msg of
   WM_CONTEXTMENU: AddPopUpMenu(@AddEditPopUp,1,wnd);
   //wnd - handle окна, для которого нужно поймать popup меню
 end;}


Андрю-ХА   (2004-01-13 15:28:00) [2]

> [5] Окей, спасибо за совет, придется так и сделать.


DVM   (2004-01-13 15:23:00) [3]


> С моей точки зрения -- не самый оптимальный вариант.

Пожалуй оптимальный. Другой вариант на порядок сложнее.


Андрю-ХА   (2004-01-13 15:12:00) [4]

> [3]
Т.е. мне "просто" надо определить 6-7 своих пунктов меню, подключить модуль Clipbrd и на OnPopup устанавливать Enabled этих самых Item'ов. С моей точки зрения -- не самый оптимальный вариант.


DVM   (2004-01-13 13:31:00) [5]


> И все равно не понятно, каким образом мне к стандартному
> меню Undo\Copy\Paste\Select all\Delete добавить свои Item'ы

Что непонятно то?
Если заменить стандартное меню своим, как сказали выше, то твоя задача трансформируется в:
"Как мне в мое меню добавить пункты Undo\Copy\Paste\Select all\Delete". Но это уже другой вопрос.


Андрю-ХА   (2004-01-13 13:29:00) [6]

И все равно не понятно, каким образом мне к стандартному меню Undo\Copy\Paste\Select all\Delete добавить свои Item'ы


Rouse_   (2004-01-13 12:28:00) [7]

У Tmemo есть свойство PopupMenu - можно заменить стандартное, также можно использовать:

The following functions are used with menus.

CheckMenuItem
CheckMenuRadioItem
CreateMenu
CreatePopupMenu
DeleteMenu
DestroyMenu
DrawMenuBar
EnableMenuItem
GetMenu
GetMenuCheckMarkDimensions
GetMenuDefaultItem
GetMenuItemCount
GetMenuItemID
GetMenuItemInfo
GetMenuItemRect
GetMenuState
GetMenuString
GetSubMenu
GetSystemMenu
HiliteMenuItem
InsertMenuItem
IsMenu
LoadMenu
LoadMenuIndirect
MenuItemFromPoint
SetMenu
SetMenuDefaultItem
SetMenuItemBitmaps
SetMenuItemInfo
TrackPopupMenu
TrackPopupMenuEx

Obsolete Functions

AppendMenu
ChangeMenu
InsertMenu
ModifyMenu
RemoveMenu

Желаю успехов


Наверх

Титульная страница Поиск, карта сайта Написать письмо