Delphi 中没有 VCL 表单的组件

发布于 2024-10-06 04:41:07 字数 202 浏览 0 评论 0原文

可能是关于现实世界中不需要的东西的问题 。但我想知道我们可以这样做吗(只是为了知识)

我可以在没有VCL形式的情况下显示vcl组件吗?我们可以创建和使用非可视化 vcl,但我们可以在可视化 vcl 中创建并使用它并使其在屏幕上可见吗?

或者至少我们可以将 VCL 放置在使用 Windows API 创建的 Form 中,

This may be a question about something not need in the real world
. but i want to know can we do it (just for knowledge)

Can i show vcl components without VCL form . We can create and use non visual vcl but can we do it in visual vcl and make it visible on screen.

Or at least can we place a VCL in side a Form created using windows API,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

向日葵 2024-10-13 04:41:07

不可以,VCL 控件(可视组件)不能存在于 VCL 表单之外。但是,您可以将 VCL 控件放置在 VCL 窗体中,然后将 VCL 窗体托管在其他类型的窗口内。 Delphi 对创建 ActiveX 控件的支持就是这样做的 - VCL 表单(我认为是 TCustomActiveForm)提供了分发给 ActiveX 的窗口句柄。您的 VCL 组件位于 TCustomActiveForm 或该类的派生类中,并且永远不知道其中的区别。

如果您愿意进行一些挖掘和提升,您也许能够避免 ActiveX 的开销。首先,检查 TCustomForm 上的 ParentHwnd 属性或 CreateParented 方法。这可能就是您所需要的 - 我记不清了,自从我看到代码以来已经有好几年了。

如果没有,您可以重写 TCustomForm 后代中的 CreateParams 方法,并将非 VCL 窗口句柄分配给 Params.WndParent 字段。在调用继承的 CreateParams 之后执行此操作,以便您获得其他所有内容的所有正常设置。您可能还需要调整 style 和 exstyle 标志,以删除表单的边框、标题等。

在此自定义表单中构造您的 VCL 控件,并调整其大小以占据整个表单区域。

您也许可以使用比 TCustomForm 更低级别的控件(例如 TCustomWinControl)来完成此操作,但您可能会丢失一些击键/加速器窗口消息处理。我知道这可以在 TCustomForm 级别完成。

No, a VCL control (visual component) cannot exist outside of a VCL form. However, you can place VCL control(s) in a VCL form, and then host the VCL form inside of some other kind of window. Delphi's support for creating ActiveX controls does this - the VCL form (TCustomActiveForm, I think) provides the window handle that is handed out to ActiveX. Your VCL components live inside that TCustomActiveForm or a descendent of that class and never know the difference.

You might be able to avoid the overhead of ActiveX if you're willing to do some digging and hoisting. First, check out the ParentHwnd property or CreateParented method on TCustomForm. That might be all you need - I can't recall off the top of my head, and it's been several years since I've seen the code.

If not, you can overridie the CreateParams method in a TCustomForm descendent and assign the non-VCL window handle to the Params.WndParent field. Do this after calling the inherited CreateParams so that you get all the normal settings on everything else. You will probably want to adjust the style and exstyle flags as well to remove the form's border, caption, etc.

Construct your VCL control in this custom form and size it to occupy the entire form area.

You might be able to do this with a lower level control than TCustomForm such as TCustomWinControl, but you may lose some keystroke / accelerator window message processing. I know it can be done at the TCustomForm level.

意中人 2024-10-13 04:41:07

是的 - 如果我很好地理解你的问题。我已经完成了完整的安装程序,没有表单、可视和非可视vcl以及api。当然,为了使其可视化(没有控制台),您需要一个窗口。

示例代码 - 无表单(打开以下 .dpr 文件并编译):

program Window;

{
   This is an example of making an application
   without using the Forms unit. Forms.pas is the
   Delphi unit that makes your programs so damn
   huge! Forms.pas has all the code for translating
   the forms you create with Delphi w/components
   into windows. 
}


uses Windows, Messages;

{$R *.RES}

var
wClass:   TWndClass;  // class struct for main window
hFont,                // handle of font
hInst,                // handle of program (hinstance)
Handle,               // handle of main window
hEncrypt,             // handle of encrypt button
hDecrypt,             // handle of decrypt button
hEdit,                // handle of main edit
hLabel,               // handle of password label
hPW:      HWND;       // handle of password edit
Msg:      TMSG;       // message struct
dEncrypt,
dDecrypt: Pointer;    // default button procedures

(*------------------------------------------------*)

// This lines everything up
procedure Resize;
var
RCT:TRect;
begin
  GetWindowRect(Handle,RCT);
  MoveWindow(hPW,230,5,RCT.Right-RCT.Left-245,24,True);
  MoveWindow(hEdit,5,34,RCT.Right-RCT.Left-20,RCT.Bottom-RCT.Top-66,True);
end;

(*------------------------------------------------*)

// This is to cleanup and stop the program
procedure ShutDown;
begin
  DeleteObject(hFont);
  UnRegisterClass('Sample Class',hInst);
  ExitProcess(hInst); //end program
end;

(*------------------------------------------------*)

// Decrypts the text in hEdit with the text in hPW
procedure Decrypt;
var
x,i,                // count variables
sText,sPW: Integer; // size of Text, PW
Text,PW:   PChar;   // buffer for Text, PW
begin
  sText:=GetWindowTextLength(hEdit)+1;
  sPW:=GetWindowTextLength(hPW)+1;
  GetMem(Text,sText);
  GetMem(PW,sPW);
  GetWindowText(hEdit,Text,sText);
  GetWindowText(hPW,PW,sPW);
  x:=0; // initialize count
  for i:=0 to sText-2 do
  begin
    Text[i]:=Chr(Ord(Text[i])-Ord(PW[x]));
    Inc(x);
    if x=(sPW-1)then x:=0;
  end;
  SetWindowText(hEdit,Text);
  FreeMem(Text);
  FreeMem(PW);
end;

(*------------------------------------------------*)

// Encrypts the text in hEdit with the text in hPW
procedure Encrypt;
var
x,i,                // count variables
sText,sPW: Integer; // size of Text, PW
Text,PW:   PChar;   // buffer for Text, PW
begin
  sText:=GetWindowTextLength(hEdit)+1;
  sPW:=GetWindowTextLength(hPW)+1;
  GetMem(Text,sText);
  GetMem(PW,sPW);
  GetWindowText(hEdit,Text,sText);
  GetWindowText(hPW,PW,sPW);
  x:=0; // initialize count
  for i:=0 to sText-2 do
  begin
    Text[i]:=Chr(Ord(Text[i])+Ord(PW[x]));
    Inc(x);
    if x=(sPW-1)then x:=0;
  end;
  SetWindowText(hEdit,Text);
  FreeMem(Text);
  FreeMem(PW);
end;

(*------------------------------------------------*)

// This function processes every message sent to the Encrypt Button
function EncryptProc(hWnd,Msg,wParam,lParam:Longint):Longint; stdcall;
var
i: Integer;
begin
  // Always pass the message to the Default procedure
  Result:=CallWindowProc(dEncrypt,hWnd,Msg,wParam,lParam);

  case Msg of
  // If the user presses TAB we're gunna switch the
  // focus over to the Decrypt button.
  WM_KEYDOWN: if wParam=9 then SetFocus(hDecrypt);
  end;

end;

(*------------------------------------------------*)

// This function processes every message sent to the Decrypt Button
function DecryptProc(hWnd,Msg,wParam,lParam:Longint):Longint; stdcall;
begin
  // Always pass the message to the Default procedure
  Result:=CallWindowProc(dEncrypt,hWnd,Msg,wParam,lParam);

  case Msg of
  // if the user presses TAB we're gunna switch
  // the focus back to the Encrypt button.
  WM_KEYDOWN: if wParam=9 then SetFocus(hEncrypt);
  end;

end;

(*------------------------------------------------*)

// This function processes every message sent to our Main window
function WindowProc(hWnd,Msg,wParam,lParam:Longint):Longint; stdcall;
begin
  // Always pass the message to the Default procedure
  Result:=DefWindowProc(hWnd,Msg,wParam,lParam);

  case Msg of
  WM_SIZE:    Resize;
  // When buttons are clicked the message is passed to
  // the parent window, so we handle it here.
  WM_COMMAND: if      lParam=hEncrypt then Encrypt
              else if lParam=hDecrypt then Decrypt;
  WM_DESTROY: ShutDown;
  end;

end;

(*------------------------------------------------*)

// This is the main program function (WinMain)
begin

  hInst:=GetModuleHandle(nil); // get the application instance
                               // hInstance returns zilch

  with wClass do
  begin
    Style:=         CS_PARENTDC;
    hIcon:=         LoadIcon(hInst,'MAINICON');
    lpfnWndProc:=   @WindowProc;
    hInstance:=     hInst;
    hbrBackground:= COLOR_BTNFACE+1;
    lpszClassName:= 'Sample Class';
    hCursor:=       LoadCursor(0,IDC_ARROW);
  end;

  // Once our class is registered we
  // can start making windows with it
  RegisterClass(wClass);

  // Create our main window
  Handle:=CreateWindow(
    'Sample Class',          // Registered Class Name
    'Encrypter', // Title of Window
    WS_OVERLAPPEDWINDOW or   // Basic Window Style
    WS_VISIBLE,              // Make it Visible
    10,                      // Left
    10,                      // Top
    400,                     // Width
    300,                     // Height
    0,                       // Parent Window Handle
    0,                       // Handle of Menu
    hInst,                   // Application Instance
    nil);                    // Structure for Creation Data

  // Create the Encrypt button
  hEncrypt:=CreateWindow(
    'Button',
    'Encrypt',
    WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,
    5,5,65,24,Handle,0,hInst,nil);

  // Create the Decrypt button
  hDecrypt:=CreateWindow(
    'Button',
    'Decrypt',
    WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,
    75,5,65,24,Handle,0,hInst,nil);

  // Create the main Edit
  hEdit:=CreateWindowEx(
    WS_EX_CLIENTEDGE, // this EX style is for the beveled edge
    'Edit',
    '',
    WS_VISIBLE or WS_CHILD or ES_LEFT or ES_MULTILINE or ES_WANTRETURN or ES_AUTOVSCROLL or WS_VSCROLL,
    5,34,380,234,Handle,0,hInst,nil);

  // Create the password Edit
  hPW:=CreateWindowEx(
    WS_EX_CLIENTEDGE,
    'Edit',
    '',
    WS_VISIBLE or WS_CHILD or ES_LEFT or ES_AUTOHSCROLL or ES_PASSWORD,
    230,5,155,24,Handle,0,hInst,nil);

  hLabel:=CreateWindow(
    'Static',
    'Password:',
    WS_VISIBLE or WS_CHILD or SS_LEFT,
    160,10,70,20,Handle,0,hInst,nil);

  // Create a custom font for our window otherwise
  // everything would use the system font (blech!)
  hFont:=CreateFont(
    -12,                           // Height
    0,                             // Width
    0,                             // Angle of Rotation
    0,                             // Orientation
    0,                             // Weight
    0,                             // Italic
    0,                             // Underline
    0,                             // Strike Out
    DEFAULT_CHARSET,               // Char Set
    OUT_DEFAULT_PRECIS,            // Precision
    CLIP_DEFAULT_PRECIS,           // Clipping
    DEFAULT_QUALITY,               // Render Quality
    DEFAULT_PITCH or FF_DONTCARE,  // Pitch & Family
    'MS Sans Serif');              // Font Name

  // Set the fonts for all our controls
  SendMessage(hEncrypt,WM_SETFONT,hFont,0);
  SendMessage(hDecrypt,WM_SETFONT,hFont,0);
  SendMessage(hEdit,WM_SETFONT,hFont,0);
  SendMessage(hPW,WM_SETFONT,hFont,0);
  SendMessage(hLabel,WM_SETFONT,hFont,0);

  // Subclass Encrypt Button (assign it a custom WindowProc)
  dEncrypt:=Pointer(GetWindowLong(hEncrypt,GWL_WNDPROC));
  SetWindowLong(hEncrypt,GWL_WNDPROC,Longint(@EncryptProc));

  // Subclass Decrypt Button
  dDecrypt:=Pointer(GetWindowLong(hDecrypt,GWL_WNDPROC));
  SetWindowLong(hDecrypt,GWL_WNDPROC,Longint(@DecryptProc));

  // The reason I don't subclass the Edit controls here
  // is because they don't do anything custom. If I wanted
  // them to Beep or something whenever you typed a "G" then
  // I would subclass them.

  // Focus on first control (otherwise people with no mouse are screwed)
  SetFocus(hEncrypt);

  // Now we loop GetMessage to process each Message in
  // our main window's message list. Every time the main
  // window recieves a message its added to the list, so
  // this loop here will eventually process it.

  while(GetMessage(Msg,Handle,0,0))do
  begin
    TranslateMessage(Msg);             // Translate any keyboard Msg's
    DispatchMessage(Msg);              // Send it to our WindowProc
  end;                                 // for processing.

end. 

yes - if i understand your question well. I have done full installation program with no form, visual and non visual vcl, and api. Of course to make it visual (no console) you need a window.

Example code - no form (open the following .dpr file and compile):

program Window;

{
   This is an example of making an application
   without using the Forms unit. Forms.pas is the
   Delphi unit that makes your programs so damn
   huge! Forms.pas has all the code for translating
   the forms you create with Delphi w/components
   into windows. 
}


uses Windows, Messages;

{$R *.RES}

var
wClass:   TWndClass;  // class struct for main window
hFont,                // handle of font
hInst,                // handle of program (hinstance)
Handle,               // handle of main window
hEncrypt,             // handle of encrypt button
hDecrypt,             // handle of decrypt button
hEdit,                // handle of main edit
hLabel,               // handle of password label
hPW:      HWND;       // handle of password edit
Msg:      TMSG;       // message struct
dEncrypt,
dDecrypt: Pointer;    // default button procedures

(*------------------------------------------------*)

// This lines everything up
procedure Resize;
var
RCT:TRect;
begin
  GetWindowRect(Handle,RCT);
  MoveWindow(hPW,230,5,RCT.Right-RCT.Left-245,24,True);
  MoveWindow(hEdit,5,34,RCT.Right-RCT.Left-20,RCT.Bottom-RCT.Top-66,True);
end;

(*------------------------------------------------*)

// This is to cleanup and stop the program
procedure ShutDown;
begin
  DeleteObject(hFont);
  UnRegisterClass('Sample Class',hInst);
  ExitProcess(hInst); //end program
end;

(*------------------------------------------------*)

// Decrypts the text in hEdit with the text in hPW
procedure Decrypt;
var
x,i,                // count variables
sText,sPW: Integer; // size of Text, PW
Text,PW:   PChar;   // buffer for Text, PW
begin
  sText:=GetWindowTextLength(hEdit)+1;
  sPW:=GetWindowTextLength(hPW)+1;
  GetMem(Text,sText);
  GetMem(PW,sPW);
  GetWindowText(hEdit,Text,sText);
  GetWindowText(hPW,PW,sPW);
  x:=0; // initialize count
  for i:=0 to sText-2 do
  begin
    Text[i]:=Chr(Ord(Text[i])-Ord(PW[x]));
    Inc(x);
    if x=(sPW-1)then x:=0;
  end;
  SetWindowText(hEdit,Text);
  FreeMem(Text);
  FreeMem(PW);
end;

(*------------------------------------------------*)

// Encrypts the text in hEdit with the text in hPW
procedure Encrypt;
var
x,i,                // count variables
sText,sPW: Integer; // size of Text, PW
Text,PW:   PChar;   // buffer for Text, PW
begin
  sText:=GetWindowTextLength(hEdit)+1;
  sPW:=GetWindowTextLength(hPW)+1;
  GetMem(Text,sText);
  GetMem(PW,sPW);
  GetWindowText(hEdit,Text,sText);
  GetWindowText(hPW,PW,sPW);
  x:=0; // initialize count
  for i:=0 to sText-2 do
  begin
    Text[i]:=Chr(Ord(Text[i])+Ord(PW[x]));
    Inc(x);
    if x=(sPW-1)then x:=0;
  end;
  SetWindowText(hEdit,Text);
  FreeMem(Text);
  FreeMem(PW);
end;

(*------------------------------------------------*)

// This function processes every message sent to the Encrypt Button
function EncryptProc(hWnd,Msg,wParam,lParam:Longint):Longint; stdcall;
var
i: Integer;
begin
  // Always pass the message to the Default procedure
  Result:=CallWindowProc(dEncrypt,hWnd,Msg,wParam,lParam);

  case Msg of
  // If the user presses TAB we're gunna switch the
  // focus over to the Decrypt button.
  WM_KEYDOWN: if wParam=9 then SetFocus(hDecrypt);
  end;

end;

(*------------------------------------------------*)

// This function processes every message sent to the Decrypt Button
function DecryptProc(hWnd,Msg,wParam,lParam:Longint):Longint; stdcall;
begin
  // Always pass the message to the Default procedure
  Result:=CallWindowProc(dEncrypt,hWnd,Msg,wParam,lParam);

  case Msg of
  // if the user presses TAB we're gunna switch
  // the focus back to the Encrypt button.
  WM_KEYDOWN: if wParam=9 then SetFocus(hEncrypt);
  end;

end;

(*------------------------------------------------*)

// This function processes every message sent to our Main window
function WindowProc(hWnd,Msg,wParam,lParam:Longint):Longint; stdcall;
begin
  // Always pass the message to the Default procedure
  Result:=DefWindowProc(hWnd,Msg,wParam,lParam);

  case Msg of
  WM_SIZE:    Resize;
  // When buttons are clicked the message is passed to
  // the parent window, so we handle it here.
  WM_COMMAND: if      lParam=hEncrypt then Encrypt
              else if lParam=hDecrypt then Decrypt;
  WM_DESTROY: ShutDown;
  end;

end;

(*------------------------------------------------*)

// This is the main program function (WinMain)
begin

  hInst:=GetModuleHandle(nil); // get the application instance
                               // hInstance returns zilch

  with wClass do
  begin
    Style:=         CS_PARENTDC;
    hIcon:=         LoadIcon(hInst,'MAINICON');
    lpfnWndProc:=   @WindowProc;
    hInstance:=     hInst;
    hbrBackground:= COLOR_BTNFACE+1;
    lpszClassName:= 'Sample Class';
    hCursor:=       LoadCursor(0,IDC_ARROW);
  end;

  // Once our class is registered we
  // can start making windows with it
  RegisterClass(wClass);

  // Create our main window
  Handle:=CreateWindow(
    'Sample Class',          // Registered Class Name
    'Encrypter', // Title of Window
    WS_OVERLAPPEDWINDOW or   // Basic Window Style
    WS_VISIBLE,              // Make it Visible
    10,                      // Left
    10,                      // Top
    400,                     // Width
    300,                     // Height
    0,                       // Parent Window Handle
    0,                       // Handle of Menu
    hInst,                   // Application Instance
    nil);                    // Structure for Creation Data

  // Create the Encrypt button
  hEncrypt:=CreateWindow(
    'Button',
    'Encrypt',
    WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,
    5,5,65,24,Handle,0,hInst,nil);

  // Create the Decrypt button
  hDecrypt:=CreateWindow(
    'Button',
    'Decrypt',
    WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,
    75,5,65,24,Handle,0,hInst,nil);

  // Create the main Edit
  hEdit:=CreateWindowEx(
    WS_EX_CLIENTEDGE, // this EX style is for the beveled edge
    'Edit',
    '',
    WS_VISIBLE or WS_CHILD or ES_LEFT or ES_MULTILINE or ES_WANTRETURN or ES_AUTOVSCROLL or WS_VSCROLL,
    5,34,380,234,Handle,0,hInst,nil);

  // Create the password Edit
  hPW:=CreateWindowEx(
    WS_EX_CLIENTEDGE,
    'Edit',
    '',
    WS_VISIBLE or WS_CHILD or ES_LEFT or ES_AUTOHSCROLL or ES_PASSWORD,
    230,5,155,24,Handle,0,hInst,nil);

  hLabel:=CreateWindow(
    'Static',
    'Password:',
    WS_VISIBLE or WS_CHILD or SS_LEFT,
    160,10,70,20,Handle,0,hInst,nil);

  // Create a custom font for our window otherwise
  // everything would use the system font (blech!)
  hFont:=CreateFont(
    -12,                           // Height
    0,                             // Width
    0,                             // Angle of Rotation
    0,                             // Orientation
    0,                             // Weight
    0,                             // Italic
    0,                             // Underline
    0,                             // Strike Out
    DEFAULT_CHARSET,               // Char Set
    OUT_DEFAULT_PRECIS,            // Precision
    CLIP_DEFAULT_PRECIS,           // Clipping
    DEFAULT_QUALITY,               // Render Quality
    DEFAULT_PITCH or FF_DONTCARE,  // Pitch & Family
    'MS Sans Serif');              // Font Name

  // Set the fonts for all our controls
  SendMessage(hEncrypt,WM_SETFONT,hFont,0);
  SendMessage(hDecrypt,WM_SETFONT,hFont,0);
  SendMessage(hEdit,WM_SETFONT,hFont,0);
  SendMessage(hPW,WM_SETFONT,hFont,0);
  SendMessage(hLabel,WM_SETFONT,hFont,0);

  // Subclass Encrypt Button (assign it a custom WindowProc)
  dEncrypt:=Pointer(GetWindowLong(hEncrypt,GWL_WNDPROC));
  SetWindowLong(hEncrypt,GWL_WNDPROC,Longint(@EncryptProc));

  // Subclass Decrypt Button
  dDecrypt:=Pointer(GetWindowLong(hDecrypt,GWL_WNDPROC));
  SetWindowLong(hDecrypt,GWL_WNDPROC,Longint(@DecryptProc));

  // The reason I don't subclass the Edit controls here
  // is because they don't do anything custom. If I wanted
  // them to Beep or something whenever you typed a "G" then
  // I would subclass them.

  // Focus on first control (otherwise people with no mouse are screwed)
  SetFocus(hEncrypt);

  // Now we loop GetMessage to process each Message in
  // our main window's message list. Every time the main
  // window recieves a message its added to the list, so
  // this loop here will eventually process it.

  while(GetMessage(Msg,Handle,0,0))do
  begin
    TranslateMessage(Msg);             // Translate any keyboard Msg's
    DispatchMessage(Msg);              // Send it to our WindowProc
  end;                                 // for processing.

end. 
吐个泡泡 2024-10-13 04:41:07

对于 VCL 组件,答案显然是肯定的。 组件可以脱离表单上下文使用,没有任何麻烦,只需通过指定nil绕过所有权机制,并在完成后手动销毁实例。

NoLongerDependsOnForm := TSomeComponent.Create(nil);
NoLongerDependsOnForm.This;
NoLongerDependsOnForm.That;
FreeAndNil(NoLongerDependsOnForm);

对于 VCL 控件,事情变得更加复杂,因为任何子窗口都需要父窗口。因此,在通用窗口中重用 TWinControl 仅在理论上可行(必须编写 VCL 存根才能使其工作)。所以,答案是否定的。

我恳求您,请停止混淆术语“表单”和“窗口”。 (延伸阅读:顶级窗口和子窗口)

For VCL components answer is clearly yes. Components are usable out of form context w/o any hassle, just bypass ownership mechanism by specifying nil and destroy instance manually when finished.

NoLongerDependsOnForm := TSomeComponent.Create(nil);
NoLongerDependsOnForm.This;
NoLongerDependsOnForm.That;
FreeAndNil(NoLongerDependsOnForm);

With VCL controls things are waaay more complex because any child window needs parent window. Thus, reusing TWinControl within generic window is possible only theoretically (have to write VCL stub to make it work). So, answer is marginally no.

And i'm begging you, please stop mixing up terms form and window. (Further reading: top-level and child windows)

心房的律动 2024-10-13 04:41:07

控件可以查找并访问所有者和父容器中的属性,将它们作为 VCL 类进行访问。如果不是,VCL 控件很可能无法工作。

避免这种情况的一种方法是将它们包装为 ActiveX 控件。然后您可以在任何支持 ActiveX 控件的语言中使用 then。

A control may look for and access properties in the owner and parent container, accessing them as VCL classes. If they are not, there are good chance the VCL control won't work.

One way to avoid that is to wrap them as ActiveX controls. Then you can use then in whatever language that supports ActiveX controls.

遇到 2024-10-13 04:41:07

这不仅仅是我自己的代码,而是对我有用的所有代码的混合器,

只需为 volvox 的答案添加这些代码(我已接受并在顶部

uses
  Windows,
  Messages,buttons,stdctrls;


var
abtn:TButton ;


begin
//  after all declaration
 abtn := TButton.Create(nil) ;
 abtn.ParentWindow := hEdit ; // use window handle but i use hedit because my button     will be hidden by another button in example
end

This is not just my own code but a mixer of all your code wich worked for me

Just add these code for volvox 's answer(which i have accepted and on the top)

uses
  Windows,
  Messages,buttons,stdctrls;


var
abtn:TButton ;


begin
//  after all declaration
 abtn := TButton.Create(nil) ;
 abtn.ParentWindow := hEdit ; // use window handle but i use hedit because my button     will be hidden by another button in example
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文