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

Вниз

Handle компонента   Найти похожие ветки 

 
DimaBr   (2005-07-22 16:48) [0]

Удалено модератором
Примечание: СПАМ


 
Digitman ©   (2005-07-22 18:02) [1]

ну все ты понял из того что тебе сказали в WinAPI !


> Как определить Handle компонента


НЕТ у TComponent никаких Handle !
Три раза повторять тебе это ?

Твой вопрос содится к СОВЕРШЕННО иному : как в дизайн-тайм в коде эксперта перечислить/идентифицировать компоненты (в составе того или иного объекта Делфи-проекта) с целью обращения к неким их св-вам/методам


 
DimaBr   (2005-07-22 18:25) [2]

Мне не нужно обращатся к их свойствам/методам, мне нужен Handle  контейнера по названию кантейнера. Неужеле всё так сложно ?


 
Джо ©   (2005-07-22 18:29) [3]


>  [2] DimaBr   (22.07.05 18:25)
> Мне не нужно обращатся к их свойствам/методам, мне нужен
> Handle  контейнера

А Handle - по-твоему это что? Какое-то заклинание? Это и есть свойство.


 
Юрий Зотов ©   (2005-07-22 18:49) [4]

> All

Пояснение.

Для представления невизуальных компонентов в design-time IDE создает на проектируемой форме дочернее окно класса TContainer (тот самый квадратик с иконкой компонента, который мы таскаем по форме). Зная сам компонент, человеку нужно получить хэндл представляющего его окна.

> Digitman

Сергей, напомни, плз, я уже подзабыл. Ты как-то говорил, что в данных окна VCL сохраняет какую-то полезную ссылку - вроде как, на экземпляр TWinControl, создавший это окно. Если это так, то задачка решается элементарно, но пока не могу найти это место в VCL.


 
DimaBr   (2005-07-22 18:54) [5]

Ладно, но мне от этого не легче. Помогите спрятать компонент.


 
DimaBr   (2005-07-22 19:04) [6]

> Юрий Зотов
Ну наконец то, уважаемый Юрий, где же вы раньше были. А то у меня уже слов нет (скуден словарный запас)


 
Юрий Зотов ©   (2005-07-22 19:12) [7]

> DimaBr   (22.07.05 19:04) [6]

Где был... в VCL копался, вот где был. И еще копаюсь пока, ждите.


 
Джо ©   (2005-07-22 19:30) [8]


> [4] Юрий Зотов ©   (22.07.05 18:49)

Это, случаем, не в TWinControl.CreateHandle?


 
Джо ©   (2005-07-22 19:34) [9]


> [8] Джо ©   (22.07.05 19:30)

Это я что-то спросонок, ляпнул... Сорри.


 
Юрий Зотов ©   (2005-07-22 20:03) [10]

> DimaBr

Скорее всего, проще будет решить задачу так. Проходите в цикле по компонентам формы. Если встретился компонент, который надо спрятать, то берете его координаты (они сидят в DesignInfo), с ними вызываете WindowFromPoint и это окно прячете (или показываете).


 
jack128 ©   (2005-07-23 00:18) [11]

Юрий Зотов ©   (22.07.05 18:49) [4]
Ты как-то говорил, что в данных окна VCL сохраняет какую-то полезную ссылку - вроде как, на экземпляр TWinControl, создавший это окно. Если это так, то задачка решается элементарно, но пока не могу найти это место в VCL.

см исходники FindControl и секцию инициализации модуля Controls, там пара атомов создается..


 
DimaBr   (2005-07-23 09:17) [12]

Привет, и огромное спасибо. Ща буду пробывать что нибудь наковырять.


 
DimaBr   (2005-07-23 12:25) [13]

Ничо не получается. Во первых DesignInfo: Longint; Как там сидят координаты - непойму. Во вторых в секции инициализации модуля Controls создаются атомы нескольких компонетов, зачем мне это ума не приложу.


 
jack128 ©   (2005-07-23 13:23) [14]

DimaBr   (23.07.05 12:25) [13]
Во первых DesignInfo: Longint; Как там сидят координаты - непойму

TSmallPoint(DesignInfo)
DimaBr   (23.07.05 12:25) [13]
Во вторых в секции инициализации модуля Controls создаются атомы нескольких компонетов, зачем мне это ума не приложу.

Я не тебе, а Юре отвечал.


 
Alexander_VC ©   (2005-07-23 15:34) [15]

> All
> DimaBr

Добрый день всем!
Я задавал подобный вопрос ранее, но никто, к сожалению, не откликнулся откликнулся. Ну да ладно. Мне это по-прежнему интересно. Прочитав эту тему, и послушав умных людей, сделал следующее:

procedure TMainForm.SpeedButton1Click(Sender: TObject);
var I: Integer;
   P: TPoint;
   wForm: TForm;
   wHandle: HWND;
begin
 // Здесь находим нужную форму
 // (на ней будем гасить невизуальные компоненты)
 wForm:= FindFormByName("Form1");

{или так
 for I:= 0 to Screen.FormCount - 1 do
   if Screen.Forms[I].Name = "Form1" then begin
     wForm:= Screen.Forms[I];
     Break;
   end;

}
 // выходим если не нашли
 if not Assigned(wForm) then
   Exit;

 // Перебираем компоненты
 for I:= 0 to wForm.ComponentCount - 1 do begin
   if (csDesigning in wForm.Components[I].ComponentState )
      and (not wForm.Components[I].InheritsFrom(TControl)) then begin
     //Полагаем, что в DesignInfo находятся
     //упакованные координаты "окна" компонента в Design time
     // Готовим перенную P        
     P.X:= LongRec(wForm.Components[I].DesignInfo).Lo;
     P.Y:= LongRec(wForm.Components[I].DesignInfo).Hi;

     wHandle := WindowFromPoint(P);
     if wHandle <> 0 then
       ShowWindow(wHandle,SW_HIDE);
   end;

 end;
end;

Окно (Handle), похоже, найдено, ShowWindow, вроде, должна работать.  Ан не работает.

Господа, еще мысли, свежие.

С уважением,
 Александр.


 
Alexander_VC ©   (2005-07-23 18:10) [16]

> All
Дальнейшие изыскания привели к следующим изменениям:

     wHandle:= 0;

     // Определяем координаты "окна" компонента в клиенте
     P.X:= LongRec(wForm.Components[I].DesignInfo).Lo + 3;
     P.Y:= LongRec(wForm.Components[I].DesignInfo).Hi + 3;

     // Пересчет координат в экранные координаты
     P:= wForm.ClientToScreen(P);

     // "Гасим" сами окна компонент
     wHandle:= WindowFromPoint(P);
     if wHandle <> 0 then
       ShowWindow(wHandle,SW_HIDE);

     // "Гасим надпипси"
     P.Y:= P.Y + 28 + 15; // надписи расположены ниже
     wHandle:= WindowFromPoint(P);
     if wHandle <> 0 then
       ShowWindow(wHandle,SW_HIDE);

Этот код работает.
Но есть моменты:
1. Если выделен невизуальный компонент, то после гашения остается  рамка выделения, наверное, в этом случае нужно менять
выделенный компонент.
2. Как узнать погашено окно компонента, хочется "гасить" и   "зажигать", как Castalia. Ибо если стенешь гасить уже погашенное, получишь HANDL окна парента (например формы) и погасишь его.
3. А самое главное все это мне самому не очень нравится.  
 Как то все по шамански.

Может кто-то решил проблему более изящно?

Всем спасибо.

С уважением,
 Александр.


 
jack128 ©   (2005-07-23 18:50) [17]

Alexander_VC ©   (23.07.05 18:10) [16]
Ты эксперт пишешь или что?? Выделенные компоненты, наверника доступны через интерфейсы OTA


 
Юрий Зотов ©   (2005-07-25 11:08) [18]

В общем, наваял я этот эксперт. Не скажу, что получилось чудо программистской мысли, но все же работает.

unit CompHider;

interface

uses
 Windows, SysUtils, Classes, Controls, Forms, StdCtrls, ComCtrls, Menus,
 DesignIntf, ToolsAPI;

type
 TComponentHider = class(TInterfacedObject, IOTANotifier, IOTAWizard, IOTAMenuWizard)
 private
   FFormRect: TRect;
 public
   { IOTANotifier }
   procedure AfterSave;
   procedure BeforeSave;
   procedure Destroyed;
   procedure Modified;
   { IOTAWizard }
   function GetIDString: string;
   function GetName: string;
   function GetState: TWizardState;
   procedure Execute;
   { IOTAMenuWizard }
   function GetMenuText: string;
 end;

 PComponentWrapper = ^TComponentWrapper;
 TComponentWrapper = packed record
   Component: TComponent;
   IconWindow: HWND;
   GrabWindows: array[0..7] of HWND;
   CaptionWindow: HWND
 end;

 TfrmComponentHider = class(TForm)
   lvComponents: TListView;
   btnOK: TButton;
   btnCancel: TButton;
   pmSelection: TPopupMenu;
   miSelectAll: TMenuItem;
   miUnselectAll: TMenuItem;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure miClick(Sender: TObject);
   procedure lvComponentsDblClick(Sender: TObject);
 private
   FDesigner: IDesigner;
   procedure Apply;
 end;

procedure Register;

implementation

{$R *.dfm}

procedure Register;
begin
 RegisterPackageWizard(TComponentHider.Create as IOTAMenuWizard)
end;

{ TComponentHider }

procedure TComponentHider.AfterSave;
begin
 // Do nothing!
end;

procedure TComponentHider.BeforeSave;
begin
 // Do nothing!
end;

procedure TComponentHider.Destroyed;
begin
 // Do nothing!
end;

procedure TComponentHider.Execute;
begin
 with TfrmComponentHider.Create(Application) do
 try
   if FFormRect.Right <> 0 then
     BoundsRect := FFormRect;
   if ShowModal = mrOK then
     Apply;
   FFormRect := BoundsRect
 finally
   Free
 end
end;

function TComponentHider.GetIDString: string;
begin
 Result := Format("Yz.%s", [StringReplace(GetName, " ", "", [rfReplaceAll])])
end;

function TComponentHider.GetMenuText: string;
begin
 Result :=  GetName + "..."
end;

function TComponentHider.GetName: string;
begin
 Result := "Component Hider"
end;

function TComponentHider.GetState: TWizardState;
begin
 Result := [wsEnabled]
end;

procedure TComponentHider.Modified;
begin
 // Do nothing!
end;

{ TfrmComponentHider }

procedure TfrmComponentHider.Apply;
const
 Command: array[Boolean] of integer = (SW_HIDE, SW_SHOW);
var
 i, j: integer;
begin
 FDesigner.SelectComponent(FDesigner.Root);
 with lvComponents.Items do
   for i := 0 to Count - 1 do
     with Item[i], PComponentWrapper(Data)^ do
     begin
       ShowWindow(IconWindow, Command[Checked]);
       for j := 0 to 7 do
         ShowWindow(GrabWindows[j], Command[Checked]);
       ShowWindow(CaptionWindow, Command[Checked])
     end
end;

procedure TfrmComponentHider.FormCreate(Sender: TObject);
var
 ParentWindow: HWND;
 P: TPoint;
 Wrapper: PComponentWrapper;

 function GetDesignWindow(const WindowClass: string): HWND;
 var
   Buff: array[0..11] of char;
 begin
   Result := ChildWindowFromPoint(ParentWindow, P);
   GetClassName(Result, Buff, SizeOf(Buff));
   if String(Buff) <> WindowClass then
     Result := 0
 end;

 procedure FindDesignWindows(Left, Top: integer);
 const
   HalfSize = 14;
   ContainerClassName = "TContainer";
 var
   i, j, k: integer;
 begin
   for i := 0 to 2 do
   begin
     P.Y := Top + i * HalfSize;
     for j := 0 to 2 do
     begin
       P.X := Left + j * HalfSize;
       if i * j <> 1 then
       begin
         k := i * 3 + j;
         if k > 3 then
           Dec(k);
         Wrapper^.GrabWindows[k] := GetDesignWindow("TGrabWindow")
       end
       else
         Wrapper^.IconWindow := GetDesignWindow(ContainerClassName)
     end
   end;
   P.X := Left + HalfSize;
   P.Y := Top + 2 * HalfSize + 10;
   Wrapper^.CaptionWindow := GetDesignWindow(ContainerClassName)
 end;

var
 IModule: IOTAModule;
 IEditor: IOTAEditor;
 IFormEditor: IOTAFormEditor;
 FormEditor: INTAFormEditor;
 RootComponent: TComponent;
 M: TMemoryStream;
 S: TStringStream;
 i: integer;
begin
 IModule := (BorlandIDEServices as IOTAModuleServices).CurrentModule;
 if IModule = nil then
   Exit;
 IEditor := IModule.CurrentEditor;
 if not Supports(IEditor, IOTAFormEditor, IFormEditor) or
    not Supports(IFormEditor, INTAFormEditor, FormEditor) then
   Exit;
 FDesigner := FormEditor.FormDesigner;
 if FDesigner = nil then
   Exit;
 RootComponent := FDesigner.Root;
 if RootComponent = nil then
   Exit;

 M := TMemoryStream.Create;
 try
   M.WriteComponent(RootComponent);
   M.Position := 0;
   S := TStringStream.Create("");
   try
     ObjectBinaryToText(M, S);
     FreeAndNil(M);
     with TStringList.Create do
     try
       Text := S.DataString;
       FreeAndNil(S);
       for i := 0 to Count - 1 do
         Strings[i] := TrimLeft(Strings[i]);
       P.X := StrToInt(TrimLeft(Values["Left "])) + GetSystemMetrics(SM_CXFRAME);
       P.Y := StrToInt(TrimLeft(Values["Top "])) + GetSystemMetrics(SM_CYCAPTION) div 2;
       ParentWindow := WindowFromPoint(P);
       if RootComponent is TDataModule then
         ParentWindow := GetWindow(ParentWindow, GW_CHILD)
     finally
       Free
     end
   finally
     S.Free
   end
 finally
   M.Free
 end;

 with RootComponent do
 begin
   for i := 0 to ComponentCount - 1 do
     if not (Components[i] is TControl) and not FDesigner.IsComponentHidden(Components[i]) then
     begin
       New(Wrapper);
       with Wrapper^ do
       try
         Component := Components[i];
         FindDesignWindows(LongRec(Component.DesignInfo).Lo, LongRec(Component.DesignInfo).Hi);
         with lvComponents.Items.Add do
         begin
           Caption := Format("%s: %s", [Component.Name, Component.ClassName]);
           Data := Wrapper;
           Checked := (IconWindow <> 0) and IsWindowVisible(IconWindow)
         end
       except
         Dispose(Wrapper);
         raise
       end
     end
 end;
 btnOK.Enabled := lvComponents.Items.Count > 0
end;

procedure TfrmComponentHider.FormDestroy(Sender: TObject);
var
 i: integer;
begin
 with lvComponents.Items do
   for i := Count - 1 downto 0 do
     Dispose(Item[i].Data)
end;

procedure TfrmComponentHider.miClick(Sender: TObject);
var
 i: integer;
begin
 with lvComponents.Items do
   for i := 0 to Count - 1 do
     Item[i].Checked := Sender = miSelectAll
end;

procedure TfrmComponentHider.lvComponentsDblClick(Sender: TObject);
var
 P: TPoint;
 Item: TListItem;
begin
 with lvComponents do
 begin
   P := ScreenToClient(Mouse.CursorPos);
   Item := GetItemAt(P.X, P.Y);
   if Item <> nil then
     Item.Checked := not Item.Checked
 end
end;

end.


 
Юрий Зотов ©   (2005-07-25 11:09) [19]

Продолжение - файл DFM формы эксперта:

object frmComponentHider: TfrmComponentHider
 Left = 369
 Top = 257
 Width = 400
 Height = 300
 BorderIcons = [biSystemMenu]
 Caption = "Component Hider"
 Color = clBtnFace
 Constraints.MinHeight = 100
 Constraints.MinWidth = 200
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -13
 Font.Name = "MS Sans Serif"
 Font.Style = []
 OldCreateOrder = False
 OnCreate = FormCreate
 OnDestroy = FormDestroy
 DesignSize = (
   392
   271)
 PixelsPerInch = 120
 TextHeight = 16
 object lvComponents: TListView
   Left = 0
   Top = 0
   Width = 305
   Height = 271
   Anchors = [akLeft, akTop, akRight, akBottom]
   Checkboxes = True
   Columns = <>
   ReadOnly = True
   PopupMenu = pmSelection
   SortType = stText
   TabOrder = 0
   ViewStyle = vsList
   OnDblClick = lvComponentsDblClick
 end
 object btnOK: TButton
   Left = 312
   Top = 207
   Width = 75
   Height = 25
   Anchors = [akRight, akBottom]
   Caption = "OK"
   Default = True
   Enabled = False
   ModalResult = 1
   TabOrder = 1
 end
 object btnCancel: TButton
   Left = 312
   Top = 241
   Width = 75
   Height = 25
   Anchors = [akRight, akBottom]
   Cancel = True
   Caption = "Cancel"
   ModalResult = 2
   TabOrder = 2
 end
 object pmSelection: TPopupMenu
   Left = 80
   Top = 56
   object miSelectAll: TMenuItem
     Caption = "Select all"
     OnClick = miClick
   end
   object miUnselectAll: TMenuItem
     Caption = "Unselect all"
     OnClick = miClick
   end
 end
end


 
DimaBr   (2005-07-26 13:51) [20]

>>> Юрий Зотов
Просто писк !!!
Однако при первом же тестинге выяснилось, что идея с координатами компонента не так уж и хороша, поскольку два компонента могут иметь одни и теже координаты и попадаться на удочку будет всё время один и тот же компонент. А так - гениально !!!



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

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

Наверх




Память: 0.54 MB
Время: 0.038 c
1-1134718960
Scorpio_md
2005-12-16 10:42
2006.01.22
Печать файла в без запуска EXCEL


14-1135758294
syte_ser78
2005-12-28 11:24
2006.01.22
Правда или приснилось?


14-1135817745
-Васек-
2005-12-29 03:55
2006.01.22
DELPHI 2005


2-1135714123
Mahab
2005-12-27 23:08
2006.01.22
CheckBox


2-1135460866
ZeFiR
2005-12-25 00:47
2006.01.22
Как реализовать следующее?