Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 05.12.2010, 03:18
3nick 3nick вне форума
Прохожий
 
Регистрация: 05.12.2010
Сообщения: 12
Репутация: 10
Счастье Выключение программы вместе с компьютером

Задача программы не зужжать и не визжать когда выключается компьютер, а спокойно выключаться вместе с ним, чего никак не могу добиться. Для этого создал форму которая должны ловить сообщение 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  
Старый 05.12.2010, 06:41
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,087
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Отдельная форма не нужна.
Достаточно просто отреагировать на это сообщение.
Хотя вообще-то для того, что бы программа не закрывалась приходится делать дополнительные телодвижения, а не наоборот.

Код:
type
  TForm1 = class(TForm)
  protected
    procedure WMQueryEndSession(var Message : TMessage); message WM_QUERYENDSESSION; 
  end;

...

procedure TForm1.WMQueryEndSession(var Message : TMessage);
begin
  Close;
end;
Ответить с цитированием
  #3  
Старый 05.12.2010, 08:56
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

все же еще проще. сообщение 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  
Старый 05.12.2010, 11:40
3nick 3nick вне форума
Прохожий
 
Регистрация: 05.12.2010
Сообщения: 12
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Отдельная форма не нужна.
Достаточно просто отреагировать на это сообщение.
Хотя вообще-то для того, что бы программа не закрывалась приходится делать дополнительные телодвижения, а не наоборот.

Код:
type
  TForm1 = class(TForm)
  protected
    procedure WMQueryEndSession(var Message : TMessage); message WM_QUERYENDSESSION; 
  end;

...

procedure TForm1.WMQueryEndSession(var Message : TMessage);
begin
  Close;
end;
я так пробовал сделать. форма почему то не реагировала на сообщения QUERYENDSESSION.
и потом здесь не раскрыто как создать форму - форма должна создасться в начале основного кода,видимо в отдельном потоке, при этом непонятно кто обрабатывает сообщения формы. у меня она зависала...
Ответить с цитированием
  #5  
Старый 05.12.2010, 11:43
3nick 3nick вне форума
Прохожий
 
Регистрация: 05.12.2010
Сообщения: 12
Репутация: 10
По умолчанию

Цитата:
Сообщение от NumLock
все же еще проще. сообщение 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;
тоже самое - не понял как сделать так чтобы форма не зависала.
например
begin
TCustomForm.create(Self);
//мой код
...
end.
таким образом форма зависнет и там не будет обрабатываться ссобщения вообще((
Ответить с цитированием
  #6  
Старый 05.12.2010, 12:02
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Цитата:
The WM_QUERYENDSESSION message is sent when the user chooses to end the Windows session or when an application calls the ExitWindows function. If any application returns zero, the Windows session is not ended. Windows stops sending WM_QUERYENDSESSION messages as soon as one application returns zero.
в Delphi при получении окном сообщения WM_QUERYENDSESSION происходит вызов события OnCloseQuery, в котором необходимо выполнить завершающие операции, типа закрыть открытые файлы, освободить занятую память ( хотя зачем? ) и т.д. и т.п.
не понял каким образом связаны WM_QUERYENDSESSION (OnCloseQuery) и код:
Код:
begin
TCustomForm.create(Self);
//мой код
...
end.
? и почему форма должна зависнуть???
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #7  
Старый 05.12.2010, 12:43
3nick 3nick вне форума
Прохожий
 
Регистрация: 05.12.2010
Сообщения: 12
Репутация: 10
По умолчанию

Код:
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.
вот код полностью... собственно ничего особенно не меняется. при завершении работы компа вместо надписи 111 выскакивает сообщение "завершение работы Project1 через 15 секнуд, завершить задачу?"
Ответить с цитированием
  #8  
Старый 05.12.2010, 13:42
Аватар для v1s2222
v1s2222 v1s2222 вне форума
Продвинутый
 
Регистрация: 07.09.2010
Сообщения: 726
Репутация: 26711
По умолчанию

Скажи, зачем тебе там сообщение? Напиши Application.Terminate и все закроется нормально.
__________________
Помогаю за Спасибо
Ответить с цитированием
  #9  
Старый 05.12.2010, 17:19
3nick 3nick вне форума
Прохожий
 
Регистрация: 05.12.2010
Сообщения: 12
Репутация: 10
Печаль

Код:
type
  TForm1 = class(TForm)
  private
  procedure WMQueryEndSession(var Message: TWMQueryEndSession); message WM_QUERYENDSESSION;
    { Private declarations }
  public
    { Public declarations }
  end;

var

  //для потока
  cs : TCriticalSection;
  UpdateThread : TUpdateThread;
  Form1: TForm1;//создаем форму для отслеживания завершения работы

procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
  application.Terminate;
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.
к сожалению то же самое - при выключении компьютера просит подождать пока завершит мою программу
Ответить с цитированием
  #10  
Старый 05.12.2010, 18:48
Аватар для v1s2222
v1s2222 v1s2222 вне форума
Продвинутый
 
Регистрация: 07.09.2010
Сообщения: 726
Репутация: 26711
По умолчанию

Поток создавать не надо, напиши так:
Код:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
// на крайняк - CanClose := True;
  Application.Terminate;
end;
__________________
Помогаю за Спасибо
Ответить с цитированием
  #11  
Старый 05.12.2010, 19:18
3nick 3nick вне форума
Прохожий
 
Регистрация: 05.12.2010
Сообщения: 12
Репутация: 10
Вопрос

наконец то с помощью API формы смог перехватить это сообщение:
Код:
function PlainWinProc (hWnd: THandle; nMsg: UINT;
  wParam, lParam: Cardinal): Cardinal;  stdcall;
begin
   case nMsg of
     WM_QUERYENDSESSION: Result:= Cardinal(true);
     WM_ENDSESSION:
     begin//ВОТ ТУТ НАЧИНАЮТСЯ ТРАБЛЫ((
        defWindowProc(hwnd,WM_CLOSE,0,0);
        Result:= Cardinal(true);
        ExitProcess(0);
     end
     else result:= defWindowProc(hwnd,nMsg,wparam,lparam);
   end;
end;
ПОСЛЕ сообщения ENDSESSION опять выскакиевает предложение подождать закрытия программы. видимо неправильное его обрабатываю. но не знаю как правильно.
Ответить с цитированием
  #12  
Старый 05.12.2010, 20:14
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

мб убрать
Код:
        defWindowProc(hwnd,WM_CLOSE,0,0);
        Result:= Cardinal(true);
?
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #13  
Старый 05.12.2010, 20:23
3nick 3nick вне форума
Прохожий
 
Регистрация: 05.12.2010
Сообщения: 12
Репутация: 10
По умолчанию

пробовал - в мсдно написано возвращать 0, сначала возвращал просто ноль
Код:
Result:=0
потом попробовал
Код:
ShutDownFlag:=true;
Result:= 0;
а потом завершал процесс
все одно и тоже(( приложение закрывается а потом предлагают подождать закрытия программы
Ответить с цитированием
  #14  
Старый 05.12.2010, 20:56
Аватар для KOOL
KOOL KOOL вне форума
Активный
 
Регистрация: 06.01.2008
Адрес: Рязань
Сообщения: 306
Версия Delphi: 2009
Репутация: 6150
По умолчанию

Блин, ну что здесь трудного? Вот развели-то! Никакой второй формы не нужно!
http://www.delphisources.ru/forum/sh...34&postcount=4
__________________
РГРТУ - ФВТ - Системы Автоматизированного ПРоектирования. ت
Ответить с цитированием
  #15  
Старый 05.12.2010, 21:46
3nick 3nick вне форума
Прохожий
 
Регистрация: 05.12.2010
Сообщения: 12
Репутация: 10
По умолчанию

попробовал все отдельно запустить - все работает.. все корректно завершается. а как тока в потоке начинаю крутить - херня((
я потоки очень плохо знаю, в чем может быть проблема?
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 13:44.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025