Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.09.2007, 22:25   #1
Kashp
Форумчанин
 
Регистрация: 05.08.2007
Сообщений: 225
По умолчанию messageBox поверх всех окон, возможно ли?

Имеется программа (главная форма скрыта от глаз). По событию таймера с этой формы выводится сообщение. Как сделать так, чтобы табличка с сообщением, например
Код:
application.MessageBox('Fatal error','Error', mb_ok+iconerror);
вот чтобы это табло с сообщением было поверх окон всех приложений. Вот можно ли такое сделать?

Последний раз редактировалось Kashp; 22.09.2007 в 22:45.
Kashp вне форума Ответить с цитированием
Старый 22.09.2007, 22:46   #2
Shuraken
Форумчанин
 
Аватар для Shuraken
 
Регистрация: 16.04.2007
Сообщений: 298
По умолчанию

Один из вариантов, это залезть в модуль Dialogs и подправить там немного исходники, чтобы при создании формы в свойствах у него стояло "показывать поверх всех окон" FormStyle := fsStayOnTop. Можно переписать и сделать свой обработчик, аналог MessageBox-а, в принципе оба варианта равноценны.
Не надо ничего усложнять. Все достаточно тривиально.
Shuraken вне форума Ответить с цитированием
Старый 22.09.2007, 23:15   #3
Kashp
Форумчанин
 
Регистрация: 05.08.2007
Сообщений: 225
По умолчанию

Цитата:
Сообщение от Shuraken Посмотреть сообщение
Один из вариантов, это залезть в модуль Dialogs и подправить там немного исходники, чтобы при создании формы в свойствах у него стояло "показывать поверх всех окон" FormStyle := fsStayOnTop. Можно переписать и сделать свой обработчик, аналог MessageBox-а, в принципе оба варианта равноценны.
А нет ли способа попроще? Если нет, то подскажи пожалуйста, что конкретно открыть и что изменить?
Kashp вне форума Ответить с цитированием
Старый 23.09.2007, 02:05   #4
Shuraken
Форумчанин
 
Аватар для Shuraken
 
Регистрация: 16.04.2007
Сообщений: 298
По умолчанию

Открываешь модуль Dialogs и ищешь там вот эту функцию:
Код:
function CreateMessageDialog(const Msg: string; DlgType: TMsgDlgType;
  Buttons: TMsgDlgButtons): TForm;
const
  mcHorzMargin = 8;
  mcVertMargin = 8;
  mcHorzSpacing = 10;
  mcVertSpacing = 10;
  mcButtonWidth = 50;
  mcButtonHeight = 14;
  mcButtonSpacing = 4;
var
  DialogUnits: TPoint;
  HorzMargin, VertMargin, HorzSpacing, VertSpacing, ButtonWidth,
  ButtonHeight, ButtonSpacing, ButtonCount, ButtonGroupWidth,
  IconTextWidth, IconTextHeight, X, ALeft: Integer;
  B, DefaultButton, CancelButton: TMsgDlgBtn;
  IconID: PChar;
  TextRect: TRect;
begin
  Result := TMessageForm.CreateNew(Application);
  with Result do
  begin
    BiDiMode := Application.BiDiMode;
    BorderStyle := bsDialog;
    Canvas.Font := Font;
    KeyPreview := True;
    OnKeyDown := TMessageForm(Result).CustomKeyDown;
    DialogUnits := GetAveCharSize(Canvas);
    HorzMargin := MulDiv(mcHorzMargin, DialogUnits.X, 4);
    VertMargin := MulDiv(mcVertMargin, DialogUnits.Y, 8);
    HorzSpacing := MulDiv(mcHorzSpacing, DialogUnits.X, 4);
    VertSpacing := MulDiv(mcVertSpacing, DialogUnits.Y, 8);
    ButtonWidth := MulDiv(mcButtonWidth, DialogUnits.X, 4);
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
    begin
      if B in Buttons then
      begin
        if ButtonWidths[B] = 0 then
        begin
          TextRect := Rect(0,0,0,0);
          Windows.DrawText( canvas.handle,
            PChar(LoadResString(ButtonCaptions[B])), -1,
            TextRect, DT_CALCRECT or DT_LEFT or DT_SINGLELINE or
            DrawTextBiDiModeFlagsReadingOnly);
          with TextRect do ButtonWidths[B] := Right - Left + 8;
        end;
        if ButtonWidths[B] > ButtonWidth then
          ButtonWidth := ButtonWidths[B];
      end;
    end;
    ButtonHeight := MulDiv(mcButtonHeight, DialogUnits.Y, 8);
    ButtonSpacing := MulDiv(mcButtonSpacing, DialogUnits.X, 4);
    SetRect(TextRect, 0, 0, Screen.Width div 2, 0);
    DrawText(Canvas.Handle, PChar(Msg), Length(Msg)+1, TextRect,
      DT_EXPANDTABS or DT_CALCRECT or DT_WORDBREAK or
      DrawTextBiDiModeFlagsReadingOnly);
    IconID := IconIDs[DlgType];
    IconTextWidth := TextRect.Right;
    IconTextHeight := TextRect.Bottom;
    if IconID <> nil then
    begin
      Inc(IconTextWidth, 32 + HorzSpacing);
      if IconTextHeight < 32 then IconTextHeight := 32;
    end;
    ButtonCount := 0;
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
      if B in Buttons then Inc(ButtonCount);
    ButtonGroupWidth := 0;
    if ButtonCount <> 0 then
      ButtonGroupWidth := ButtonWidth * ButtonCount +
        ButtonSpacing * (ButtonCount - 1);
    ClientWidth := Max(IconTextWidth, ButtonGroupWidth) + HorzMargin * 2;
    ClientHeight := IconTextHeight + ButtonHeight + VertSpacing +
      VertMargin * 2;
    Left := (Screen.Width div 2) - (Width div 2);
    Top := (Screen.Height div 2) - (Height div 2);
    if DlgType <> mtCustom then
      Caption := LoadResString(Captions[DlgType]) else
      Caption := Application.Title;
    if IconID <> nil then
      with TImage.Create(Result) do
      begin
        Name := 'Image';
        Parent := Result;
        Picture.Icon.Handle := LoadIcon(0, IconID);
        SetBounds(HorzMargin, VertMargin, 32, 32);
      end;
    TMessageForm(Result).Message := TLabel.Create(Result);
    with TMessageForm(Result).Message do
    begin
      Name := 'Message';
      Parent := Result;
      WordWrap := True;
      Caption := Msg;
      BoundsRect := TextRect;
      BiDiMode := Result.BiDiMode;
      ALeft := IconTextWidth - TextRect.Right + HorzMargin;
      if UseRightToLeftAlignment then
        ALeft := Result.ClientWidth - ALeft - Width;
      SetBounds(ALeft, VertMargin,
        TextRect.Right, TextRect.Bottom);
    end;
    if mbOk in Buttons then DefaultButton := mbOk else
      if mbYes in Buttons then DefaultButton := mbYes else
        DefaultButton := mbRetry;
    if mbCancel in Buttons then CancelButton := mbCancel else
      if mbNo in Buttons then CancelButton := mbNo else
        CancelButton := mbOk;
    X := (ClientWidth - ButtonGroupWidth) div 2;
    for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
      if B in Buttons then
        with TButton.Create(Result) do
        begin
          Name := ButtonNames[B];
          Parent := Result;
          Caption := LoadResString(ButtonCaptions[B]);
          ModalResult := ModalResults[B];
          if B = DefaultButton then Default := True;
          if B = CancelButton then Cancel := True;
          SetBounds(X, IconTextHeight + VertMargin + VertSpacing,
            ButtonWidth, ButtonHeight);
          Inc(X, ButtonWidth + ButtonSpacing);
          if B = mbHelp then
            OnClick := TMessageForm(Result).HelpButtonClick;
        end;
  end;
end;
И в нее и вставляешь строчку
FormStyle := fsStayOnTop;
Понятно?
Не надо ничего усложнять. Все достаточно тривиально.

Последний раз редактировалось rpy3uH; 29.07.2008 в 20:17.
Shuraken вне форума Ответить с цитированием
Старый 23.09.2007, 10:14   #5
Kashp
Форумчанин
 
Регистрация: 05.08.2007
Сообщений: 225
По умолчанию

А после какой строки в этой функции надо вписать
"FormStyle := fsStayOnTop;" ?
Kashp вне форума Ответить с цитированием
Старый 23.09.2007, 10:39   #6
Shuraken
Форумчанин
 
Аватар для Shuraken
 
Регистрация: 16.04.2007
Сообщений: 298
По умолчанию

with Result do
begin
BiDiMode := Application.BiDiMode;
BorderStyle := bsDialog;
Canvas.Font := Font;
KeyPreview := True;
FormStyle := fsStayOnTop;
Не надо ничего усложнять. Все достаточно тривиально.
Shuraken вне форума Ответить с цитированием
Старый 23.09.2007, 12:24   #7
Kashp
Форумчанин
 
Регистрация: 05.08.2007
Сообщений: 225
По умолчанию

Цитата:
Сообщение от Shuraken Посмотреть сообщение
with Result do
begin
BiDiMode := Application.BiDiMode;
BorderStyle := bsDialog;
Canvas.Font := Font;
KeyPreview := True;
FormStyle := fsStayOnTop;
Вписал сюда эту строку, сохранил файл. Открыл свой проект, скомпилировал его (в нем через определенное время вылетает табло с сообщением. Сама форма скрыта), запускаю. Затем открываю, например, Word, жду сообщение, оно появляется, но опять же, чтобы его увидеть, пришлось сворачивать Word
Что я неправильно сделал?
Kashp вне форума Ответить с цитированием
Старый 23.09.2007, 12:34   #8
Shuraken
Форумчанин
 
Аватар для Shuraken
 
Регистрация: 16.04.2007
Сообщений: 298
По умолчанию

Хмм... теоретически это должно было сработать... надо думать дальше.
Не надо ничего усложнять. Все достаточно тривиально.
Shuraken вне форума Ответить с цитированием
Старый 23.09.2007, 20:57   #9
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Kashp я как-то пытался сделать подобное, у меня программа в трее сидела и я хотел чтобы она выдавала MessageBox и он был поверх всех окон. Скажу лишь, что у меня ничего не вышло )
И тут дело вовсе не в StayOnTop. Как я только не пробовал.
Единственное чего я добился - оранжевой подсветки на панели задач.

p.s. Так что присоединяюсь к вопросу )
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 23.09.2007, 21:41   #10
still_alive
Great Code Monkey
Форумчанин
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 533
По умолчанию

Просто к флагам модальности добавить MB_SYSTEMMODAL?
still_alive вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поверх всех окон delphin100 Общие вопросы Delphi 2 19.04.2008 19:00
Поверх всех окон Патрон Общие вопросы Delphi 1 18.04.2008 16:57
Форма поверх всех окон (!!!) Viteef Общие вопросы Delphi 12 29.06.2007 00:22
Форма поверх всех окон. Kamikadze_666 Общие вопросы Delphi 1 16.05.2007 07:10
чекбокс - поверх всех окон puz Компоненты Delphi 6 11.05.2007 17:58