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

Вниз

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

Наверх




Память: 0.53 MB
Время: 0.045 c
4-1131705864
Eraser
2005-11-11 13:44
2006.01.22
Разрешения в winNT/2K/XP


1-1134561283
Antonn
2005-12-14 14:54
2006.01.22
Оконная тень


11-1117927273
rofl
2005-06-05 03:21
2006.01.22
Kol Memo: strange output on Items[] if item is just one byte


3-1132838076
DimMih
2005-11-24 16:14
2006.01.22
Работа с DBGrid


8-1123675290
Voron
2005-08-10 16:01
2006.01.22
Как сделать снимок экрана





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский