![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Задача программы не зужжать и не визжать когда выключается компьютер, а спокойно выключаться вместе с ним, чего никак не могу добиться. Для этого создал форму которая должны ловить сообщение QUERYENDSESSION и мессагить об этом (потом переделаю чтоб закрывалась):
Код:
function PlainWinProc (hWnd: THandle; nMsg: UINT;
wParam, lParam: Cardinal): Cardinal; export; stdcall;
var
Rect: TRect;
// id_Button = 100;
begin
Result := 0;
case nMsg of
wm_Create:
// create button
CreateWindowEx (0, // extended styles
'BUTTON', // predefined class
'&Click here', // caption
ws_Child or ws_Visible or ws_Border
or bs_PushButton, // styles
0, 0, // position: see wm_Size
200, 80, // size
hwnd, // parent
100, // identifier (not a menu handle)
hInstance, // application id
nil); // init info pointer
wm_Size:
begin
// get the size of the client window
GetClientRect (hWnd, Rect);
// move the button window
SetWindowPos (
GetDlgItem (hWnd, 100), // button handle
0, // zOrder
Rect.Right div 2 - 100,
Rect.Bottom div 2 - 40,
0, 0, // new size
swp_NoZOrder or swp_NoSize);
end;
wm_Command:
// if it comes from the button
if LoWord (wParam) = 100 then
// if it is a click
if HiWord (wParam) = bn_Clicked then
MessageBox (hWnd, 'Button Clicked',
'Plain API 2', MB_OK);
wm_Destroy:
begin
showmessage('WM_CLOSE');
end;
WM_CLOSE: showmessage('WM_CLOSE');
WM_QUIT: showmessage('WM_QUIT');
WM_QUERYENDSESSION: showmessage('WM_QUERYENDSESSION');
WM_ENDSESSION: showmessage('WM_ENDSESSION');
//PostQuitMessage (0);
else
Result := DefWindowProc (hWnd, nMsg, wParam, lParam);
end;
end;
procedure TUpdateThread.Execute;
var
hWnd: THandle;
Msg: TMsg;
WndClassEx: TWndClassEx;
begin
// initialize the window class structure
WndClassEx.cbSize := sizeOf (TWndClassEx);
WndClassEx.lpszClassName := 'PlainWindow';
WndClassEx.style := cs_VRedraw or cs_HRedraw;
WndClassEx.hInstance := HInstance;
WndClassEx.lpfnWndProc := @PlainWinProc;
WndClassEx.cbClsExtra := 0;
WndClassEx.cbWndExtra := 0;
WndClassEx.hIcon := LoadIcon (hInstance, MakeIntResource ('MAINICON'));
WndClassEx.hIconSm := LoadIcon (hInstance, MakeIntResource ('MAINICON'));
WndClassEx.hCursor := LoadCursor (0, idc_Arrow);;
WndClassEx.hbrBackground := 0;//GetStockObject (white_Brush);
WndClassEx.lpszMenuName := nil;
// register the class
if RegisterClassEx (WndClassEx) = 0 then
MessageBox (0, 'Invalid class registration',
'Plain API', MB_OK)
else
begin
hWnd := CreateWindowEx (
ws_Ex_OverlappedWindow, // extended styles
WndClassEx.lpszClassName, // class name
'Plain API Demo', // title
ws_OverlappedWindow, // styles
cw_UseDefault, 0, // position
cw_UseDefault, 0, // size
0, // parent window
0, // menu
HInstance, // instance handle
nil); // initial parameters
if hWnd = 0 then
MessageBox (0, 'Window not created',
'Plain API', MB_OK)
else
begin
//ShowWindow (hWnd, sw_ShowNormal);
while GetMessage (Msg, 0, 0, 0) do
begin
TranslateMessage (Msg);
DispatchMessage (Msg);
end;
end;
end;
end;
begin
cs := TCriticalSection.Create;
UpdateThread := TUpdateThread.Create(true);
UpdateThread.Resume();
end;но ничего не происхоодит при выключении компа - он спрашивает точно ли я хочу завершить программу или подождать 15 сек! |
|
#2
|
|||
|
|||
|
Отдельная форма не нужна.
Достаточно просто отреагировать на это сообщение. Хотя вообще-то для того, что бы программа не закрывалась приходится делать дополнительные телодвижения, а не наоборот. Код:
type
TForm1 = class(TForm)
protected
procedure WMQueryEndSession(var Message : TMessage); message WM_QUERYENDSESSION;
end;
...
procedure TForm1.WMQueryEndSession(var Message : TMessage);
begin
Close;
end; |
|
#3
|
||||
|
||||
|
все же еще проще. сообщение WM_QUERYENDSESSION вызывает событие OnCloseQuery. см. код:
Код:
unit Forms;
TCustomForm = class(TScrollingWinControl)
private
procedure WMQueryEndSession(var Message: TWMQueryEndSession); message WM_QUERYENDSESSION;
procedure TCustomForm.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
Message.Result := Integer(CloseQuery and CallTerminateProcs);
end;
function TCustomForm.CloseQuery: Boolean;
var
I: Integer;
begin
if FormStyle = fsMDIForm then
begin
Result := False;
for I := 0 to MDIChildCount - 1 do
if not MDIChildren[i].CloseQuery then Exit;
end;
Result := True;
if Assigned(FOnCloseQuery) then FOnCloseQuery(Self, Result);
end; |
|
#4
|
|||
|
|||
|
Цитата:
например begin TCustomForm.create(Self); //мой код ... end. таким образом форма зависнет и там не будет обрабатываться ссобщения вообще(( |
|
#5
|
||||
|
||||
|
Цитата:
) и т.д. и т.п.не понял каким образом связаны WM_QUERYENDSESSION (OnCloseQuery) и код: Код:
begin TCustomForm.create(Self); //мой код ... end. |
|
#6
|
|||
|
|||
|
Код:
type
TForm1 = class(TForm)
private
procedure WMQueryEndSession(var Message: TWMQueryEndSession); message WM_QUERYENDSESSION;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;//создаем форму для отслеживания завершения работы
//для потока
cs : TCriticalSection;
UpdateThread : TUpdateThread;
procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
showmessage('111111');
Message.Result := Integer(CallTerminateProcs);
end;
procedure TUpdateThread.Execute;
var
MyForm :TFORM;
begin
MyForm := Form1.Create(Application);
MyForm.Show();
end;
begin
//создаем поток на отслеживание выключения компьютера
cs := TCriticalSection.Create;
UpdateThread := TUpdateThread.Create(true);
UpdateThread.Resume();
end. |
|
#7
|
|||
|
|||
|
Цитата:
и потом здесь не раскрыто как создать форму - форма должна создасться в начале основного кода,видимо в отдельном потоке, при этом непонятно кто обрабатывает сообщения формы. у меня она зависала... |