Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.58 MB
Время: 0.012 c
1-1124210289
Андрей Молчанов
2005-08-16 20:38
2005.09.11
TShellTreeView, TShellListView и TShellComboBox


14-1124340419
CHES
2005-08-18 08:46
2005.09.11
Архив конференции "основная" за 2004 год


1-1124254857
jiny
2005-08-17 09:00
2005.09.11
Удаление последней строки в текстовом файле


1-1124617108
MeF Dei Corvi
2005-08-21 13:38
2005.09.11
XML и Delphi


14-1124179033
syte_ser78
2005-08-16 11:57
2005.09.11
Последнее усилие перед отпуском.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский