Форум: "Компоненты";
Текущий архив: 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