<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=112368&amp;view=findpost&amp;p=835664</guid>
        <pubDate>Wed, 24 Aug 2005 08:02:47 +0000</pubDate>
        <title>Контекстное меню для файла</title>
        <link>https://forum.sources.ru/index.php?showtopic=112368&amp;view=findpost&amp;p=835664</link>
        <description><![CDATA[Rouse_: Как показать контекстное меню для конкретного файла?<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">////////////////////////////////////////////////////////////////////////////////</div><div class="code_line">//</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">// &nbsp;* Unit Name : Unit1</div><div class="code_line">// &nbsp;* Purpose &nbsp; : Демо отображения системного контекстного меню эксплорера</div><div class="code_line">// &nbsp;* Author &nbsp; &nbsp;: Александр (Rouse_) Багель</div><div class="code_line">// &nbsp;* Version &nbsp; : 1.00</div><div class="code_line">// &nbsp;****************************************************************************</div><div class="code_line">//</div><div class="code_line">&nbsp;</div><div class="code_line">unit Unit1;</div><div class="code_line">&nbsp;</div><div class="code_line">interface</div><div class="code_line">&nbsp;</div><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,</div><div class="code_line">&nbsp;&nbsp;Dialogs, StdCtrls,</div><div class="code_line">&nbsp;&nbsp;// Чтоб все заработало - подключаем вот эти 2 юнита</div><div class="code_line">&nbsp;&nbsp;ShlObj,</div><div class="code_line">&nbsp;&nbsp;ActiveX;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TForm1 = class(TForm)</div><div class="code_line">&nbsp;&nbsp; &nbsp;Button1: TButton;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure Button1Click(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Form1: TForm1;</div><div class="code_line">&nbsp;</div><div class="code_line">implementation</div><div class="code_line">&nbsp;</div><div class="code_line">{$R *.dfm}</div><div class="code_line">&nbsp;</div><div class="code_line">// Это для работы самого меню, как оконного элемента</div><div class="code_line">function MenuCallback(Wnd: HWND; Msg: UINT; WParam: WPARAM;</div><div class="code_line">&nbsp;LParam: LPARAM): LRESULT; stdcall;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;ContextMenu2: IContextMenu2;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;case Msg of</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_CREATE:</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ContextMenu2 := IContextMenu2(PCreateStruct(lParam).lpCreateParams);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SetWindowLong(Wnd, GWL_USERDATA, Longint(ContextMenu2));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result := DefWindowProc(Wnd, Msg, wParam, lParam);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_INITMENUPOPUP:</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ContextMenu2 := IContextMenu2(GetWindowLong(Wnd, GWL_USERDATA));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ContextMenu2.HandleMenuMsg(Msg, wParam, lParam);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_DRAWITEM, WM_MEASUREITEM:</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ContextMenu2 := IContextMenu2(GetWindowLong(Wnd, GWL_USERDATA));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ContextMenu2.HandleMenuMsg(Msg, wParam, lParam);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result := 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := DefWindowProc(Wnd, Msg, wParam, lParam);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Это для создания самого меню, как оконного элемента</div><div class="code_line">function CreateMenuCallbackWnd(const ContextMenu: IContextMenu2): HWND;</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;IcmCallbackWnd = &#39;ICMCALLBACKWND&#39;;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;WndClass: TWndClass;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;FillChar(WndClass, SizeOf(WndClass), #0);</div><div class="code_line">&nbsp;&nbsp;WndClass.lpszClassName := PChar(IcmCallbackWnd);</div><div class="code_line">&nbsp;&nbsp;WndClass.lpfnWndProc := @MenuCallback;</div><div class="code_line">&nbsp;&nbsp;WndClass.hInstance := HInstance;</div><div class="code_line">&nbsp;&nbsp;Windows.RegisterClass(WndClass);</div><div class="code_line">&nbsp;&nbsp;Result := CreateWindow(IcmCallbackWnd, IcmCallbackWnd, WS_POPUPWINDOW, 0,</div><div class="code_line">&nbsp;&nbsp; &nbsp;0, 0, 0, 0, 0, HInstance, Pointer(ContextMenu));</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure GetProperties(Path: String; MousePoint: TPoint; WC: TWinControl);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;CoInit, AResult: HRESULT;</div><div class="code_line">&nbsp;&nbsp;CommonDir, FileName: String;</div><div class="code_line">&nbsp;&nbsp;Desktop, ShellFolder: IShellFolder;</div><div class="code_line">&nbsp;&nbsp;pchEaten, Attr: Cardinal;</div><div class="code_line">&nbsp;&nbsp;PathPIDL: PItemIDList;</div><div class="code_line">&nbsp;&nbsp;FilePIDL: array [0..1] of PItemIDList;</div><div class="code_line">&nbsp;&nbsp;ShellContextMenu: HMenu;</div><div class="code_line">&nbsp;&nbsp;ICMenu: IContextMenu;</div><div class="code_line">&nbsp;&nbsp;ICMenu2: IContextMenu2;</div><div class="code_line">&nbsp;&nbsp;PopupMenuResult: BOOL;</div><div class="code_line">&nbsp;&nbsp;CMD: TCMInvokeCommandInfo;</div><div class="code_line">&nbsp;&nbsp;M: IMAlloc;</div><div class="code_line">&nbsp;&nbsp;ICmd: Integer;</div><div class="code_line">&nbsp;&nbsp;CallbackWindow: HWND;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Первичная инициализация</div><div class="code_line">&nbsp;&nbsp;ShellContextMenu := 0;</div><div class="code_line">&nbsp;&nbsp;Attr := 0;</div><div class="code_line">&nbsp;&nbsp;PathPIDL := nil;</div><div class="code_line">&nbsp;&nbsp;CallbackWindow := 0;</div><div class="code_line">&nbsp;&nbsp;CoInit := CoInitializeEx(nil, COINIT_MULTITHREADED);</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Получаем пути и имя фала</div><div class="code_line">&nbsp;&nbsp; &nbsp;CommonDir := ExtractFilePath(Path);</div><div class="code_line">&nbsp;&nbsp; &nbsp;FileName := ExtractFileName(Path);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Получаем указатель на интерфейс рабочего стола</div><div class="code_line">&nbsp;&nbsp; &nbsp;if SHGetDesktopFolder(Desktop) &#60;&#62; S_OK then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;RaiseLastOSError;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Если работаем с папкой</div><div class="code_line">&nbsp;&nbsp; &nbsp;if FileName = &#39;&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Получаем указатель на папку &quot;Мой компьютер&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if (SHGetSpecialFolderLocation(0, CSIDL_DRIVES, PathPIDL) &#60;&#62; S_OK) or</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;(Desktop.BindToObject(PathPIDL, &nbsp;nil, &nbsp;IID_IShellFolder,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Pointer(ShellFolder)) &#60;&#62; S_OK) then RaiseLastOSError;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Получаем указатель на директорию</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ShellFolder.ParseDisplayName(WC.Handle, nil, StringToOleStr(CommonDir),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pchEaten, FilePIDL[0], Attr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Получаем указатель на контектсное меню папки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;AResult := ShellFolder.GetUIObjectOf(WC.Handle, 1, FilePIDL[0],</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;IID_IContextMenu, nil, Pointer(ICMenu));</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Получаем указатель на папку &quot;Мой компьютер&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if (Desktop.ParseDisplayName(WC.Handle, nil, StringToOleStr(CommonDir),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pchEaten, PathPIDL, Attr) &#60;&#62; S_OK) or</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;(Desktop.BindToObject(PathPIDL, nil, IID_IShellFolder,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Pointer(ShellFolder)) &#60;&#62; S_OK) then RaiseLastOSError;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Получаем указатель на файл</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ShellFolder.ParseDisplayName(WC.Handle, nil, StringToOleStr(FileName),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pchEaten, FilePIDL[0], Attr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Получаем указатель на контектсное меню файла</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;AResult := ShellFolder.GetUIObjectOf(WC.Handle, 1, FilePIDL[0],</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;IID_IContextMenu, nil, Pointer(ICMenu));</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Если указатель на конт. меню есть, делаем так:</div><div class="code_line">&nbsp;&nbsp; &nbsp;if Succeeded(AResult) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ICMenu2 := nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Создаем меню</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;ShellContextMenu := CreatePopupMenu;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Производим его наполнение</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if Succeeded(ICMenu.QueryContextMenu(ShellContextMenu, 0,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;1, FFF, CMF_EXPLORE)) and</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Succeeded(ICMenu.QueryInterface(IContextMenu2, ICMenu2)) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CallbackWindow := CreateMenuCallbackWnd(ICMenu2);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Показываем меню</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;PopupMenuResult := TrackPopupMenu(ShellContextMenu, TPM_LEFTALIGN or TPM_LEFTBUTTON</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;or TPM_RIGHTBUTTON or TPM_RETURNCMD,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MousePoint.X, MousePoint.Y, 0, CallbackWindow, nil);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ICMenu2 := nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Если был выбран какой либо пункт меню:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if PopupMenuResult then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Индекс этого пункта будет лежать в ICmd</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ICmd := LongInt(PopupMenuResult) - 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Заполняем структуру TCMInvokeCommandInfo</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;FillChar(CMD, SizeOf(CMD), #0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;with CMD do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cbSize := SizeOf(CMD);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hWND := WC.Handle;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lpVerb := MakeIntResource(ICmd);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nShow := SW_SHOWNORMAL;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Выполняем InvokeCommand с заполненной структурой</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;AResult := ICMenu.InvokeCommand(CMD);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if AResult &#60;&#62; S_OK then RaiseLastOSError;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Освобождаем занятые ресурсы чтобы небыло утечки памяти</div><div class="code_line">&nbsp;&nbsp; &nbsp;if FilePIDL[0] &#60;&#62; nil then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Для освобождения использем IMalloc</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SHGetMAlloc(M);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if M &#60;&#62; nil then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;M.Free(FilePIDL[0]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;M:=nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if PathPIDL &#60;&#62; nil then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;SHGetMAlloc(M);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if M &#60;&#62; nil then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;M.Free(PathPIDL);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;M:=nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if ShellContextMenu &#60;&#62;0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DestroyMenu(ShellContextMenu);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if CallbackWindow &#60;&#62; 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DestroyWindow(CallbackWindow);</div><div class="code_line">&nbsp;&nbsp; &nbsp;ICMenu := nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp;ShellFolder := nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Desktop := nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if CoInit = S_OK then CoUninitialize;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Пример использования</div><div class="code_line">procedure TForm1.Button1Click(Sender: TObject);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;pt: TPoint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;GetCursorPos(pt);</div><div class="code_line">&nbsp;&nbsp;GetProperties(&#39;E:\Guardant\INSTDRV.INI&#39;, pt, Self);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
Автор: <a class='tag-url' href='http://forum.sources.ru/index.php?showuser=19443' target='_blank'>Rouse_</a>]]></description>
        <author>Rouse_</author>
        <category>ActiveX, COM, DCOM, CORBA, MIDAS, интерфейсы, OLE, DDE</category>
      </item>
	
      </channel>
      </rss>
	