ShellApi
michal_lot
Jeżeli możesz popraw ten artykuł według zaleceń, które możesz znaleźć na stronie [[Artykuły do poprawy]]. Po dopracowaniu tego tekstu można usunąć ten komunikat.
2 Zestawienie wybranych procedur i funkcji modułu ShellAPI
3 Przykład z ShellExecute
4 Aplikacja w tray'u (na pasku zadań, obok zegara)
Krótki opis
Moduł jest podstawową biblioteką Delphi, służy do komunikowania się programu z otoczeniem Windows. Na przykład, dzięki procedurze ShellExecute
możemy otworzyć dany plik. Poniżej zestaw funkcji i procedur:
Zestawienie wybranych procedur i funkcji modułu ShellAPI
function DragQueryFile(Drop: HDROP; FileIndex: UINT; FileName: PChar; cb: UINT): UINT; stdcall;
function DragQueryFileA(Drop: HDROP; FileIndex: UINT; FileName: PAnsiChar; cb: UINT): UINT; stdcall;
function DragQueryFileW(Drop: HDROP; FileIndex: UINT; FileName: PWideChar; cb: UINT): UINT; stdcall;
function DragQueryPoint(Drop: HDROP; var Point: TPoint): BOOL; stdcall;
procedure DragFinish(Drop: HDROP); stdcall;
procedure DragAcceptFiles(Wnd: HWND; Accept: BOOL); stdcall;
function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,
Directory: PChar; ShowCmd: Integer): HINST; stdcall;
function ShellExecuteA(hWnd: HWND; Operation, FileName, Parameters,
Directory: PAnsiChar; ShowCmd: Integer): HINST; stdcall;
function ShellExecuteW(hWnd: HWND; Operation, FileName, Parameters,
Directory: PWideChar; ShowCmd: Integer): HINST; stdcall;
function FindExecutable(FileName, Directory: PChar; Result: PChar): HINST; stdcall;
function FindExecutableA(FileName, Directory: PAnsiChar; Result: PAnsiChar): HINST; stdcall;
function FindExecutableW(FileName, Directory: PWideChar; Result: PWideChar): HINST; stdcall;
function CommandLineToArgvW(lpCmdLine: LPCWSTR; var pNumArgs: Integer): PPWideChar; stdcall;
function ShellAbout(Wnd: HWND; szApp, szOtherStuff: PChar; Icon: HICON): Integer; stdcall;
function ShellAboutA(Wnd: HWND; szApp, szOtherStuff: PAnsiChar; Icon: HICON): Integer; stdcall;
function ShellAboutW(Wnd: HWND; szApp, szOtherStuff: PWideChar; Icon: HICON): Integer; stdcall;
function DuplicateIcon(hInst: HINST; Icon: HICON): HICON; stdcall;
function ExtractAssociatedIcon(hInst: HINST; lpIconPath: PChar;
var lpiIcon: Word): HICON; stdcall;
function ExtractAssociatedIconA(hInst: HINST; lpIconPath: PAnsiChar;
var lpiIcon: Word): HICON; stdcall;
function ExtractAssociatedIconW(hInst: HINST; lpIconPath: PWideChar;
var lpiIcon: Word): HICON; stdcall;
function ExtractIcon(hInst: HINST; lpszExeFileName: PChar;
nIconIndex: UINT): HICON; stdcall;
function ExtractIconA(hInst: HINST; lpszExeFileName: PAnsiChar;
nIconIndex: UINT): HICON; stdcall;
function ExtractIconW(hInst: HINST; lpszExeFileName: PWideChar;
nIconIndex: UINT): HICON; stdcall;
Przykład z ShellExecute
Teraz pokaże użycie najczęściej używanych procedur:
...
uses
..., ShellAPI;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(Handle, 'Open', 'C:\Test.txt', nil, nil, SW_NORMAL);
end;
Nazwa argumentu | Podana wartość | Opis |
---|---|---|
hWnd | Handle | uchwyt |
Operation | Open | otwiera plik |
FileName | C:\Text.txt | nazwa pliku do otwarcia |
Parameters | nil | parametry otwarcia |
Directory | nil | ścieżka katalogu |
ShowCmd | SW_NORMAL | typ pokazania okna (tu: standardowe) |
SW_MINIMALIZED | zminimalizowane | |
SW_MAXIMIZED | zmaksymalizowane |
Aplikacja w tray'u (na pasku zadań, obok zegara)
Są dwie rzeczy, które trzeba wziąć pod uwagę tworząc aplikację do tray'a. Pierwsza to "ukrycie" aplikacji przed Windows. Mimo, że aplikacje takie wyglądają i zachowują się jak zwykłe aplikacje Windows, nie można się na nie przełączyć przy użyciu Alt+Tab
ani nie mają swojego przycisku na pasku zadań. Tym zajmiemy się najpierw.
Każde okno posiadające styl WS_EX_TOOLWINDOW
ani nie ma przycisku na pasku zadań ani nie można się na nie przełączyć. Z początku może wydawać się właściwym ustawienie tego stylu przy użyciu CreateParams
. Niestety nie zadziała to dla formy. Tu mała dygresja. Główna forma aplikacji nie jest oknem (w terminologii Windows) aplikacji. Obiekt aplikacji ma swoje własne okno - nie można go zobaczyć ale ono "tam" jest. To jest właśnie to okno, do którego należy przypisać styl WS_EX_TOOLWINDOW
. Gdzie więc należy wstawić kod? Oczywiście w źródle projektu. Po wybraniu View->Project Source
należy skopiować poniższy kod:
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
{ To jest wymagane aby znana była stała WS_EX_TOOLWINDOW i pozostałe }
Windows;
{$R *.RES}
var
{ Deklaracja zmiennej do przyjęcia informacji o stylu okna }
ExtendedStyle: Integer;
begin
Application.Initialize;
{ Pobranie informacji o oknie aplikacji przy użyciu GetWindowLong }
ExtendedStyle := GetWindowLong(Application.HandlApplication.Handle, GWL_EXSTYLE);
{ Teraz ustawiamy styl rozszerzony przy użyciu operacji na bitach
Przekształca to okno z okna-aplikacji do okna-narzędzia }
SetWindowLong(Application.Handle, GWL_EXSTYLE,
ExtendedStyle or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
A teraz aby utworzyć właściwy efekt aplikacji w tray'u będziemy potrzebowali przede wszystkim głównej formy aplikacji. Połóż na formie komponent z klasy TPopupMenu
. Będzie to główny interfejs do naszej aplikacji. Popatrz na poniższy kod:
unit Unit1;
{ Poniższe umieszcza aplikację w trayu.
Jest to główna forma aplikacji. Posiada ona menu popup używane do
wyświetlenia formy i zamknięcia aplikacji.
Używając modułu ShellAPI w prosty sposób pokażemy ikonę aplikacji w tray'u
i spowodujemy aby reagowała na kliknięcia myszą }
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ShellAPI, ExtCtrls, Menus;
type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
ShowMainForm1: TMenuItem;
N1: TMenuItem;
ExitApplication1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure ShowMainForm1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ExitApplication1Click(Sender: TObject);
private
procedure WndProc(var Msg : TMessage); override;
public
IconNotifyData : TNotifyIconData;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
{ Zostawiamy tylko przycisk zamykający okno }
BorderIcons := [biSystemMenu];
{ Teraz wypełniamy rekord IconNotifyData tak aby przyjmował
komunikaty wysyłane do aplikacji i pokazywał "dymki" podpowiedzi. }
with IconNotifyData do
begin
hIcon := Application.Icon.Handle;
uCallbackMessage := WM_USER + 1;
cbSize := SizeOf(IconNotifyData);
Wnd := Handle;
uID := 100;
uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
end;
{ Kopiujemy tytuł aplikacji jako "dymek" }
StrPCopy(IconNotifyData.szTip, Application.Title);
{ Dodajemy ikonę do tray'a }
Shell_NotifyIcon(NIM_ADD, @IconNotifyData);
end;
procedure TForm1.WndProc(var Msg: TMessage);
var
P: TPoint;
begin
if (Msg.Msg = WM_USER + 1) and (Msg.lParam = WM_RBUTTONDOWN) then
begin
GetCursorPos(P);
PopupMenu1.Popup(P.X, P.Y);
end;
inherited;
end;
{ To jedna z procedur obsługi elementów menu }
procedure TForm1.ShowMainForm1Click(Sender: TObject);
begin
Form1.Show;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caNone;
Form1.Hide;
end;
procedure TForm1.ExitApplication1Click(Sender: TObject);
begin
Shell_NotifyIcon(NIM_DELETE, @IconNotifyData);
Application.ProcessMessages;
Application.Terminate;
end;
end.
Jak widać nie ma wiele do zrobienia. Ale ważne jest aby rozumieć co zrobiliśmy w metodzie OnCreate
i jakie znaczenie ma rekord IconNotifyData
. Jest to rekord zdefiniowany w module ShellAPI, który przechowuje informację o ikonie w tray'u. Zauważ flagi, których użyliśmy: NIF_MESSAGE + NIF_ICON + NIF_TIP
. Oznaczają one kolejno: obsługę komunikatów dla aplikacji, pokazywanie ikony aplikacji i pokazywanie "dymku" z podpowiedzią.
Następna sprawa to nadpisanie procedury WndProc (skrót od WindowProcedure). Dostaje ona wszystkie komunikaty przesyłane do okna i zachowuje się jak centralna rozdzielnia komunikatów. Można przejąć obsługę komunikatu pisząc własną jego obsługę i wywołując odziedziczoną procedurę. Przy obsłudze komunikatu sprawdzamy czy jest to nasz własny (WM_USER + 1
) zdefiniowany w zmiennej IconNotifyData
oraz czy nastąpiło kliknięcie prawym przyciskiem myszy. Pozostałe komunikaty przesyłamy bez zmian. [...]
michal_lot
A ja orty już naprawiłem. Naliczyłem ich 666.
michal_lot, Ty się lepiej naucz pisać po polsku analfabeto. Ktos, nieźle z tymi polskimi literkami zauważyłeś :)
Ten artykuł jak i kody znalazłem na http://www.murphy.website.pl/faq.php?action=dzial&id=3. O dziwo, tam też są problemy z polskimi literkami :P Plagiat?
To sobie zainstaluj polską. A dlaczego w dalszej części artykułu są polskie litery? Przepisane (skopiowane) skąś? A dlaczego są dwa tragiczne błędy ortograficzne w pierwszych zdaniach, to już nie jest wina klawiatury.
Do poprawy.