Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.09.11;
Скачать: CL | DM;

Вниз

TAllegroMDIBar: проблема с сообщением WM_GETTEXT под "стилем XP"   Найти похожие ветки 

 
kaif ©   (2004-10-23 11:31) [0]

На основе кода ElegantMDI и частично кода Игоря Шевченко я разработал свой компонент панели кнопок для MDI.
Но у меня проблема - под "стилем XP" экранных настроек в XP на кнопках не высвечиваются надписи, хотя картинки высвечиваются. Кнопки TBarButton у меня потомки TSpeedButton, панель TAllegroMDIBar - потомок обычной TPanel.
Под "классическим стилем" в XP и в других ОС все нормально.
Проблема в том, что в "стиле XP" не возникает почему-то WM_GETTEXT, где у меня назначается Caption кнопке из заголовка MDIChild окна.
 Почему это так и что делать?
 Ниже привожу полный код компонента:

unit AllegroMDI;

interface

uses
 Windows, Classes, Graphics, Messages, Controls, Forms, ExtCtrls, Buttons, Menus, StdCtrls,
 Dialogs, SysUtils;

type
 TAllegroMDIBar = class(TPanel)
 private
   Form: TForm;
   FFlat: Boolean;
   OldWndClientProc: Pointer;
   InstanceWndClientProc: Pointer;
   Popup: TPopupMenu;
   procedure RedrawButtons;
   procedure PopupMenuPopup(Sender: TObject);
   procedure MinimizeMDIWindow(Sender: TObject);
   procedure CloseMDIWindow(Sender: TObject);
   procedure RestoreMDIWindow(Sender: TObject);
   procedure MaximizeMDIWindow(Sender: TObject);
 protected
   procedure WndClientProc(var Message: TMessage); virtual;
 public
   constructor Create(AOwner: TComponent); override;
 published
   property Flat: boolean read FFlat write FFlat;
 end;

 TBarButton = class(TSpeedButton)
 private
   Handle: THandle;
   AllegroMDIBar: TAllegroMDIBar;
   OldChildWndProc: Pointer;
   InstanceChildWndProc: Pointer;
   procedure GetButtonGlyph;
 protected
   procedure ChildWndProc(var Message: TMessage); virtual;
   procedure BarButtonClick(Sender: TObject);
   procedure BarButtonDblClick(Sender: TObject);
 public
   constructor Create(AOwner: TComponent);override;
   destructor Destroy; override;
 end;

const MaxButtonWidth = 140;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents("Samples", [TAllegroMDIBar]);
end;

{ TBarButton }

procedure TBarButton.ChildWndProc(var Message: TMessage);
begin
 case Message.Msg of
 WM_GETTEXT: //нет этого события под стилем XP!!!    begin
     Message.Result:= CallWindowProc(OldChildWndProc, Handle, Message.Msg, Message.WParam, Message.LParam);
     Caption := PChar(Message.LParam);
     Hint := Caption;
     Exit;
   end;
 WM_MDIACTIVATE:
   begin
     if HWND(Message.LParam) = Handle then Down := True;
     if HWND(Message.WParam) = Handle then Down := False;
   end;
 WM_SETICON:
     GetButtonGlyph;
 WM_DESTROY:
   begin
     self.Free;
     AllegroMDIBar.RedrawButtons;
   end;
 end;
 Message.Result:= CallWindowProc(OldChildWndProc, Handle, Message.Msg, Message.WParam, Message.LParam);
end;

procedure TBarButton.BarButtonClick(Sender: TObject);
begin
 BringWindowToTop(Handle);
end;

constructor TBarButton.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 OnClick := BarButtonClick;
 OnDblClick := BarButtonDblClick;
 Top := 1;
 GroupIndex := 1;
 Width := 140;
 AllowAllUp := False;
 Glyph.Width := 16;
 Glyph.Height := 16;
 Glyph.TransparentColor := clCaptionText;
 Layout := blGlyphLeft;
 Margin := 2;
end;

destructor TBarButton.Destroy;
begin
 SetWindowLong(Handle, GWL_WNDPROC, Longint(OldChildWndProc));
 FreeObjectInstance(InstanceChildWndProc);
 inherited Destroy;
end;

procedure TBarButton.BarButtonDblClick(Sender: TObject);
begin
 ShowWindow(Handle, SW_RESTORE);
end;

{ TAllegroMDIBar }

 


 
kaif ©   (2004-10-23 11:31) [1]

продолжение кода:

constructor TAllegroMDIBar.Create(AOwner: TComponent);
var
 Component: TComponent;
 mi: TMenuItem;
begin
 inherited Create(AOwner);

 Flat := False;
 BevelOuter := bvNone;
 Height := 23;
 Align := alBottom;
 Caption := "";

 if not(csDesigning in ComponentState) then
 begin
   Component := Owner;
   while Assigned(Component) and not (Component is TForm) do
     Component:= Component.Owner;
   if not Assigned(Component) then
     Exit;
   Form := Component as TForm;

   if Form.Handle=Form.ClientHandle then ; // without this don""t work :o??????

   if (not (csDesigning in ComponentState)) and (Form.FormStyle=fsMDIForm) then begin
     InstanceWndClientProc := MakeObjectInstance(WndClientProc);
     OldWndClientProc := Pointer(GetWindowLong(Form.ClientHandle, GWL_WNDPROC));
     SetWindowLong(Form.ClientHandle, GWL_WNDPROC, Longint(InstanceWndClientProc));
   end;

   Popup := TPopupMenu.Create(Form);
   Popup.OnPopup := PopupMenuPopup;
   mi := TMenuItem.Create(Form);
   mi.Caption := "Âîññòàíîâèòü";
   mi.OnClick := RestoreMDIWindow;
   mi.Bitmap.Handle := LoadBitmap(0, PChar(OBM_RESTORED));
   Popup.Items.Add(mi);

   mi := TMenuItem.Create(Form);
   mi.Caption := "Ñâåðíóòü";
   mi.OnClick := MinimizeMDIWindow;
   mi.Bitmap.Handle := LoadBitmap(0, PChar(OBM_REDUCED));
   Popup.Items.Add(mi);

   mi := TMenuItem.Create(Form);
   mi.Caption := "Ðàçâåðíóòü";
   mi.OnClick := MaximizeMDIWindow;
   mi.Bitmap.Handle := LoadBitmap(0, PChar(OBM_ZOOMD));
   Popup.Items.Add(mi);

   mi := TMenuItem.Create(Form);
   mi.Caption := "-";
   Popup.Items.Add(mi);

   mi := TMenuItem.Create(Form);
   mi.Caption := "Çàêðûòü";
   mi.OnClick := CloseMDIWindow;
   Popup.Items.Add(mi);
 end;
end;

procedure TAllegroMDIBar.PopupMenuPopup(Sender: TObject);
begin
 with Popup do
 begin
   if IsIconic(TBarButton(PopupComponent).Handle) then
   begin
     Items[0].Enabled := True;
     Items[1].Enabled := False;
     Items[2].Enabled := True;
   end
   else
   begin
     Items[0].Enabled := IsZoomed(TBarButton(PopupComponent).Handle);
     Items[1].Enabled := True;
     Items[2].Enabled := not Items[0].Enabled;
   end;
   TBarButton(PopupComponent).Down := True;
   TBarButton(PopupComponent).Click;
 end;
end;

procedure TAllegroMDIBar.RedrawButtons;
var
ButtonWidth : Integer;
I : Integer;
begin
Invalidate();
if ComponentCount = 0 then
  Exit;
ButtonWidth := (Width - (ComponentCount * 2)) div ComponentCount;
if ButtonWidth > MaxButtonWidth then
  ButtonWidth := MaxButtonWidth;

  for I:=0 to Pred(ComponentCount) do
  with TBarButton(Components[I]) do
  begin
    Width := ButtonWidth;
    Left := I * (Width + 2);
  end;
end;

procedure TAllegroMDIBar.MaximizeMDIWindow(Sender: TObject);
begin
 ShowWindow(TBarButton(Popup.PopupComponent).Handle, SW_MAXIMIZE);
end;

procedure TAllegroMDIBar.MinimizeMDIWindow(Sender: TObject);
begin
 ShowWindow(TBarButton(Popup.PopupComponent).Handle, SW_MINIMIZE);
end;

procedure TAllegroMDIBar.RestoreMDIWindow(Sender: TObject);
begin
 ShowWindow(TBarButton(Popup.PopupComponent).Handle, SW_RESTORE);
end;

procedure TAllegroMDIBar.CloseMDIWindow(Sender: TObject);
begin
 Form.ActiveMDIChild.Close;
end;

procedure TAllegroMDIBar.WndClientProc(var Message: TMessage);
begin
 case Message.Msg of
   WM_MDICREATE:
     begin
       Message.Result := CallWindowProc(OldWndClientProc, Form.ClientHandle, Message.Msg, Message.WParam, Message.LParam);
       with TBarButton.Create(Self) do
       begin
         Handle := Message.Result;
         AllegroMDIBar := self;
         Parent := self;
         PopupMenu := self.Popup;
         Flat := self.Flat;
         ShowHint := self.ShowHint;
         InstanceChildWndProc := MakeObjectInstance(ChildWndProc);
         OldChildWndProc := Pointer(GetWindowLong(Handle,GWL_WNDPROC));
         SetWindowLong(Handle, GWL_WNDPROC, Longint(InstanceChildWndProc));
       end;
       RedrawButtons;
       Exit;
     end;
   WM_DESTROY:
     begin
       SetWindowLong(Form.ClientHandle, GWL_WNDPROC, Longint(OldWndClientProc));
       FreeObjectInstance(InstanceWndClientProc);
     end;
   WM_SIZE:
     begin
       RedrawButtons;
     end;
 end;
 Message.Result:= CallWindowProc(OldWndClientProc, Form.ClientHandle, Message.Msg, Message.WParam, Message.LParam);
end;

procedure TBarButton.GetButtonGlyph;
var
 i: integer;
 IconHandle: THandle;
begin
 with AllegroMDIBar.Form do
 for i := 0 to MDIChildCount - 1 do
 if MDIChildren[i].Handle = self.Handle then
 begin
   IconHandle := MDIChildren[i].Icon.Handle;
   if IconHandle = 0 then
     IconHandle := Application.Icon.Handle;
   Glyph.Canvas.FillRect(Rect(0,0,15,15));
   DrawIconEx(Glyph.Canvas.Handle, 0, 0, IconHandle,
      Glyph.Width, Glyph.Height, 0, 0, DI_NORMAL);
   exit;
 end;
end;

end.


 
Gero ©   (2004-10-23 11:37) [2]

Это странно, так как SpeedButton это не CommonControl и от тем по идее зависить не должен.


 
kaif ©   (2004-10-23 12:54) [3]

Ситуация такая: сам SpeedButton нормально работает, если ему Caption присвоить. У меня не вызывается само присвоение. Так как я перехватываю сообщение Windows WM_GETTEXT, посылаемое дочернему окну (MDIChild-у) и пытаюсь из него извлечь заголовок окна, чтобы записхать его в SpeedButton.Caption. Этот кусок кода при "стиле XP" не работает. А как мне узнать заголовок окна при стиле XP иначе - я просто не знаю. При других стилях код работает нормально.
procedure TBarButton.ChildWndProc(var Message: TMessage);
begin

case Message.Msg of
WM_GETTEXT: //нет этого события под стилем XP!!!    
 begin
    Message.Result:= CallWindowProc(OldChildWndProc, Handle, Message.Msg, Message.WParam, Message.LParam);
    Caption := PChar(Message.LParam); //присваиваю заголовку кнопки заголовок окна.
    Hint := Caption;
    Exit;
  end;
 и так далее...


 
Gero ©   (2004-10-23 17:31) [4]

Я не могу понять зачем это, Caption ведь в наследнике нормально присваевается.


 
jack128 ©   (2004-10-23 18:21) [5]

kaif ©   (23.10.04 11:31)

>TBarButton = class(TSpeedButton)
>  


>destructor TBarButton.Destroy;
>begin
>  SetWindowLong(Handle, GWL_WNDPROC,
>Longint(OldChildWndProc));
>  
Откуда HAndle у speedbutton"a ?? Он же вроде GraphicControl...


 
Gero ©   (2004-10-23 22:05) [6]


> jack128 ©   (23.10.04 18:21)



> TBarButton = class(TSpeedButton)
>  private
>    Handle: THandle;



 
jack128 ©   (2004-10-24 12:47) [7]

Gero ©   (23.10.04 22:05) [6]угу, туплю...
kaif ©   (23.10.04 12:54) [3]
как я перехватываю сообщение Windows WM_GETTEXT, посылаемое дочернему окну (MDIChild-у)


непонятно только зачем..Мне кажется нужно перехватывать WM_SETTEXT. Именно этим соообщением устанавливается новый заголовок окна..


 
kaif ©   (2004-10-24 21:38) [8]

2 jack128 ©
Handle - это я добавил. Извиняюсь. Это не Handle кнопки - я просто назвал, видно, неудачно. Это Handle окна, связанного с кнопкой. Сообщение WM_SETTEXT я тоже пробовал перехватить - под "стилем XP" его тоже нет!!! (установлено экспериментально). Вообще кто-нибудь знает, что такое этот "стиль XP", есть ли по нему какая-то документация или спецификация?

 Мне нужно какое-то событие, которое сработает, когда Caption окана кто-то решит поменять в процессе работы программы. Чтобы кнопка на панели, связанная с этим окном, тоже поменяла свой заголовок. Пока что под "стилем XP" у меня все кнопки оказались голыми - картинки есть, а надписей - нет.
Можете поставить этот компонент у себя (у кого XP и установлен стиль мыльницы) и посмотреть. Кстати, сам AllegroMDIBar получился очень неплохим. Ошибок там нет (как в ElegentMDI, где имелась утечка ресурсов, плохая перестновка кнопок и глюки ToolBar-а). Единственная проблема - та, о которой я говорю. Еще я хочу создать у длинных надписей в конце многоточие. Пока идей здесь особых нет, кроме того, чтобы создать абстрактную канву (в TBitmap), и вывести туда текст каким-нибудь DrawText с опцией обрезания с многоточием. Там есть такой режим (у функции Windows), когда обрезанная строка возвращается в виде текста. Конечно все это выглядит громоздко, но другого способа обрезать текст я пока не вижу. Может быть через GetMetric рассчитать какой-нибудь. Я плохо знаю функции API, может чего-то просто не знаю...
 Если поможете с событием (сообщением) для перехвата присвоения заголока окна - буду признателен. Я могу разместить этот компонент как Freeware с исходным текстом и совместным авторством с теми, кто поможет в этом вопросе.


 
Игорь Шевченко ©   (2004-10-24 22:06) [9]


>  Мне нужно какое-то событие, которое сработает, когда Caption
> окана кто-то решит поменять в процессе работы программы.


WinEventHook (EVENT_OBJECT_NAMECHANGE) возникает всегда в процессе исполнения оконным менеджером сообщения WM_SETTEXT, но, полагаю, что разбираться с SetWinEventHook будет тоже довольно громоздко.

К сожалению, у меня сейчас нет Windows XP, так что я не могу проверить и найти способ обойти ситуацию.

Менеджер тем в Windows XP перехватывает следующие функции:
DefWindowProc, DrawCaption и перерисовку главного окна MDI.
Вся обработка изменения заголовка дочернего окна MDI выполняется без обмена сообщениями с окном клиентской части MDI или с окном главной формы.


 
Gero ©   (2004-10-24 22:40) [10]


> Вообще кто-нибудь знает, что такое этот "стиль XP", есть
> ли по нему какая-то документация или спецификация?

http://www.rsdn.ru/article/winshell/themes.xml

Провел небольшое исследование.
Если сделать SendMessage(SomeMDIChild, WM_SETTEXT, 0, 0) то WM_SETTEXT все нормально, и нужный код выполняется.
Если же делать Perform(что происходит при установке Caption формы), то WM_SETTEXT не происходит.


 
Игорь Шевченко ©   (2004-10-24 23:45) [11]

Кстати, дочернее окно MDI сообщение WM_SETTEXT получает, согласно которому оно не только обновляет свой заголовок, но и при максимизированном состоянии изменяет заголовок главного окна.
Я бы при создании кнопки на тулбаре вызывал бы GetWindowText, чтобы получить заголовок окна в момент создания кнопки, а затем перекрыл бы у дочернего окна оконную процедуру, в которой бы отслеживал сообщение WM_SETTEXT, после выполнения по CallWindowProc вызывал бы снова GetWindowText

Немного подробнее о том, что такое "Стиль XP". Реализация его состоит в том, что ряд стандартных функции user32 по обработке оконных сообщений, по рисованию (DrawCaption, DrawFrameControl) и по получению параметров оформления окна и системы (GetSystemMetrics, SystemParametersInfo) перекладывается на uxtheme.dll, в которой эти же функции реализованы с поддержкой тем XP. Для того, чтобы такой механизм был возможен, в user32 был введен набор функций под общим названием UserApiHooking
(RegisterUserApiHook, UnregisterUserApiHook). Более того, о том, что используются темы, знает также и диспетчер подсистемы управления окнами (win32k.sys). В этом случае диспетчер изменяет обработку сообщений по умолчанию, с тем, чтобы избежать конликтов при рисовании окон, меню, и т.п.

Gero ©   (24.10.04 22:40) [10]

> Если же делать Perform(что происходит при установке Caption
> формы), то WM_SETTEXT не происходит


А как же меняется заголовок окна ? Он, помимо WM_SETTEXT никак не поменяется (разве что по DrawCaption(Ex))


 
Gero ©   (2004-10-24 23:59) [12]


> Игорь Шевченко ©   (24.10.04 23:45)
> А как же меняется заголовок окна ? Он, помимо WM_SETTEXT никак не
> поменяется (разве что по DrawCaption(Ex))

Безусловно,  WM_SETEXT посылается окну.
Но в данном примере (
case Message.Msg of
WM_SETTEXT:

)
WM_SETTEXT произойдет по отправке сообщения только через SendMessage, но не через делфийский Perform...
Очень странно на первый взгляд.


 
jack128 ©   (2004-10-25 01:00) [13]

Gero ©   (24.10.04 23:59) [12]
но не через делфийский Perform...
Очень странно на первый взгляд.


Почему странно? Проверять лень ;-) но вроде все логично. Peform в результате отправляет все сообщения в DefWndProc, а это - старая процедура. Та что была до подмены её kaif"ом. Чтобы коректно работал Peform нужно привоить этому свойству новое значение - InstanceChildWndProc.. Только врядли менеджер тем ХP что нибудь знает о методе Peform..


 
Gero ©   (2004-10-25 10:43) [14]


> Peform в результате отправляет все сообщения в DefWndProc

Не, в WndProc.


 
jack128 ©   (2004-10-25 12:00) [15]

function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
begin
 ...
 if Self <> nil then WindowProc(Message);
 ...
end;
WindowProc по умолчанию = WndProc;

procedure TControl.WndProc(var Message: TMessage);
begin
 ...
 Dispatch(Message);
end;

procedure TWinControl.DefaultHandler(var Message);
begin
 if FHandle <> 0 then
 begin
   with TMessage(Message) do
   begin
     if (Msg = WM_CONTEXTMENU) and (Parent <> nil) then
     begin
       Result := Parent.Perform(Msg, WParam, LParam);
       if Result <> 0 then Exit;
     end;
     case Msg of
       WM_CTLCOLORMSGBOX..WM_CTLCOLORSTATIC:
         Result := SendMessage(LParam, CN_BASE + Msg, WParam, LParam);
       CN_CTLCOLORMSGBOX..CN_CTLCOLORSTATIC:
         begin
           SetTextColor(WParam, ColorToRGB(FFont.Color));
           SetBkColor(WParam, ColorToRGB(FBrush.Color));
           Result := FBrush.Handle;
         end;
     else
       Result := CallWindowProc(FDefWndProc, FHandle, Msg, WParam, LParam);
     end;
     if Msg = WM_SETTEXT then
       SendDockNotification(Msg, WParam, LParam);
   end;
 end
 ...
end
Так что почти все сообщения за рядом исключений приходят в DefWndProc...


 
Gero ©   (2004-10-25 12:06) [16]


> jack128 ©   (25.10.04 12:00)

Интересно то, как могут темы влиять на это.


 
kaif ©   (2004-10-26 03:02) [17]

Спасибо всем!
 Мне многое прояснил jack128 ©   (25.10.04 01:00) [13] - я вдруг сообразил, что если вместо того, чтобы регистрировать новую оконную процедуру с помощью SetWindowLong, нужно просто подменить метод, назначенный свойству WindowProc и в подмененном методе после вызывать старый метод WndProc. Тогда Perform заработает.
 А Игорь Шевченко ©   (24.10.04 23:45) [11] вернул меня к идее работать с WM_SETTEXT. Только вместо SendMessage я просто задействовал Perform.

 case Message.Msg of
   WM_MDICREATE:
     begin
       Message.Result := CallWindowProc(OldWndClientProc, Form.ClientHandle, Message.Msg, Message.WParam, Message.LParam);
       with TBarButton.Create(Self) do
       begin
         AllegroMDIBar := self;
         Parent := self;
         PopupMenu := self.Popup;
         Flat := self.Flat;
         ShowHint := self.ShowHint;
         with AllegroMDIBar.Form do
         for i := 0 to MDIChildCount - 1 do
         if MDIChildren[i].Handle =  THandle(Message.Result) then
         begin
           MDIChildForm := MDIChildren[i];
           break;
         end;
         OldChildWndProc := MDIChildForm.WindowProc;
         MDIChildForm.WindowProc := ChildWndProc;
         MDIChildForm.Perform(WM_SETTEXT, 0, longint(PChar(MDIChildForm.Caption)));
       end;
       RedrawButtons;
       Exit;
     end;


 Это гораздо более "Дельфийское решение".
 Удалось также вставить многоточие в конце длинной надписи на кнопке, выводя надпись с помощью DrawText в виртуальной канве:

 ScreenDC := GetDC(0);
 try
   DC := CreateCompatibleDC(ScreenDC);
   ...
 

Полностью исходный текст компонента лежит здесь:

http://www.gaapinvest.com/zipprog1/AllegroMDI.zip

Ксати, только сейчас заметил... Вызов Perform можно выкинуть, так как процедура RedrawButtons все равно заменит все Caption кнопок. Мне кажется, неплохой получился компонент.

Еще раз всем спасибо большое.


 
jack128 ©   (2004-10-26 04:22) [18]

kaif ©   (26.10.04 3:02) [17]
Еще раз всем спасибо большое.


Алле, kaif, куда?? какое спасибо???  Или после всех этих манипуляций твой компонент стал работать и с темами XP??


 
kaif ©   (2004-10-26 05:50) [19]

2 jack128 ©   (26.10.04 04:22) [18]
Вопрос я не понял. В каком смысле "работать с темами"?
Да, компонент сейчас нормально работает в "стиле XP" тоже. В том смысле, что надписи видны и картинкии тоже. Ничего не глючит, все пристойно. Кнопки, разумеется, не мыльные, а человеческие (классические). Могут быть плоскими (свойство Flat нужно установить у AllegroMDIBar)
Скачай - посмотри.

http://www.gaapinvest.com/zipprog1/AllegroMDI.zip

Установи компонент, создай MDI-проект, кинь на главное окно компонент и поюзай. Если что не так - сообщи.
:)


 
Gero ©   (2004-10-26 08:45) [20]


> kaif ©   (26.10.04 05:50)

А корректную прорисовку под XP с темами делать не будешь?

Мне некоторые моменты не понравились.
Например, нужно давать возможность перекрыть встроенное меню еще в DT.
Да и что-то типа ShowImages не помешало бы.


 
jack128 ©   (2004-10-26 12:08) [21]

kaif ©   (26.10.04 5:50) [19]
Вопрос я не понял. В каком смысле "работать с темами"?

Ну первоначальный вопрос был:
kaif ©   (23.10.04 11:31)
Но у меня проблема - под "стилем XP" экранных настроек в XP на кнопках не высвечиваются надписи

Причина с том, что не приходят сообщения WM_GET/SETTEXT

kaif ©   (26.10.04 5:50) [19]
Да, компонент сейчас нормально работает в "стиле XP" тоже. В том смысле, что надписи видны


Странно..Твои изменения заключались в отказе от подмены оконной процедуры, но я не вижу как это может повлиять на приход сообщений WM_SET/GETTEXT при использовании стиля XP...


 
kaif ©   (2004-10-26 12:58) [22]

2 Gero ©   (26.10.04 08:45) [20]
Мне некоторые моменты не понравились.
Например, нужно давать возможность перекрыть встроенное меню еще в DT.

Объясни, я не понял.
Да и что-то типа ShowImages не помешало бы.
С этим согласен. Добавлю.

2 jack128 ©   (26.10.04 12:08) [21]
Поясню. Мне нужно было поймать момент, когда програма, написанная на Delphi, изменяет заголовок окна (неважно, зачем). Например, разработчик вызвал:

 with TMyChildForm.Create(Application) do
 begin
   Caption := "Вася Пупкин";
 end;


 Сначала сработало сообщение, которое у меня породило кнопку на панели, а сразу после этого разработчик программы сделал присвоение Caption := "Вася Пупкин";
 Мне всеравно, как поймать это событие.
 Так как выяснилось, что при присвоении Caption вызывается в конце-концов метод Perform, в который передается сообщение WM_SETTEXT, но это сообщение не доходит до оконной процедуры в "стиле XP". Зато доходит до обработчика метода Perform, так как это делает сама VCL. Поэтому я и подменяю метод, а не процедуру. Мне ведь все равно, как именно VCL в конечном итоге будет менять заголовок окна. Мне важно, чтобы если уж VCL способна изменить заголовок окна (пусть даже самым таинственным способом), то пусть одновременно изменится и заголовок кнопки. А если VCL не сможет изменить заголовок окна, так как Билл Гейтс и дальше решил издеваться над Win32, то пусть и кнопка останется без изменений заголовка.


 
Gero ©   (2004-10-26 15:41) [23]


> kaif ©   (26.10.04 12:58)
> Объясни, я не понял.

Например, мне не нравится твое PopupMenu, и я хочу свое с другими пунктами.
Или просто хочу добавить пару пунктов к твоему, не создавая своего.
Дай мне возможность сделать это.

Добавь события - типа OnButtonClick, OnButtonMouseDown и.т.п.

Потом - под XP с темами кнопки-то рисуются стандартными, не поддерживающими темы.
Неплохо бы добавить поддержку тем.


 
Gero ©   (2004-10-27 09:53) [24]


> kaif ©   (26.10.04 12:58

Как я понял, пожелания не приняты?


 
kaif ©   (2004-10-27 12:39) [25]

2 Gero ©
Не то, чтобы не приняты.  
Я старался сделать самый простой и банальный компонент. Так как мне он нужен был для программы Allegro.
Насчет замены popup-меню я готов подумать.
Я не знаю, что такое поддержка тем, честно говоря. Если знаешь - добавь сам. Исходный текст у тебя есть. Если получится что-то более качественное в результате - я буду только рад. Выложим где-нибудь как Freeware.


 
Gero ©   (2004-10-27 21:41) [26]


> kaif ©   (27.10.04 12:39)

Давай мыло, скину.


 
kaif ©   (2004-10-28 10:39) [27]

ashot@vallex.ru


 
kaif ©   (2004-10-28 17:06) [28]

Жаль, кладовка закрыта.
Усовершенствованный вариант (со свойством ShowIcons) положил на
http://www.gaapinvest.com/zipprog1/AllegroMDI.zip

Gero ©   (27.10.04 21:41) [26]
Только сейчас получил твой вариант по почте. Еще не смотрел.


 
kaif ©   (2004-10-29 16:44) [29]

2 Gero ©
Твой компонент у меня заработал под XP Home Edition! С темами и без. Правда ты забыл прислать файл *.dfm , но я понял, что ты хотел сказать.
У меня рука не поднимается выставлять твой компонент Freeware.
Подумай, может стоить разделить на два компонента. Один (мой) AllegroMDIBar, второй - GeroMDIBar. Мой сделать freeware,  а твой - с платным исходником. Подумай.


 
Gero ©   (2004-10-30 11:41) [30]


> kaif ©   (29.10.04 16:44)

Это личная переписка уже пошла, пиши мылом.



Страницы: 1 вся ветка

Текущий архив: 2005.09.11;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.025 c
4-1121849920
Antonn
2005-07-20 12:58
2005.09.11
Пример использования формы(на WinAPI) в dll.


14-1124307013
lookin
2005-08-17 23:30
2005.09.11
ZoneAlarm не дает спокойно жить


1-1124478201
-=[ASH]=-
2005-08-19 23:03
2005.09.11
Визуальный редактор


1-1124514569
Navi
2005-08-20 09:09
2005.09.11
Сохранить положение сплиттера


4-1121860429
Vasia
2005-07-20 15:53
2005.09.11
Как получить номер текущего видео режима