2010-12-04 2 views
3

Этот может быть вопроса о том, что не нужно в реальном времени . но я хочу знать, можем ли мы это сделать (только для знания)Компоненты без VCL Forms in Delphi

Могу ли я показать компоненты vcl без формы VCL. Мы можем создавать и использовать не визуальные vcl, но можем ли мы сделать это на визуальном vcl и сделать его видимым на экране.

Или, по крайней мере, мы можем разместить VCL в стороне Форма создана с использованием Windows API,

+1

Да, возможно, это возможно, но, возможно, не очень удобно. – 2010-12-04 14:04:39

+0

Это замечательный комментарий, потому что вы сказали ДА! но КАК – VibeeshanRC 2010-12-04 14:06:11

+0

Почему вы спрашиваете, как в комментарии? В Q вы говорите, что вам не нужно это делать. Я ожидаю, что это можно сделать. Лично я бы разместил его в потомке TForm и родил его с помощью свойства ParentWnd. – 2010-12-04 17:27:41

ответ

5

Нет, элемент VCL (визуальный компонент) не может существовать вне формы VCL. Тем не менее, вы можете размещать элементы управления VCL в форме VCL, а затем размещать форму VCL внутри какого-либо другого окна. Поддержка Delphi для создания элементов ActiveX делает это - форма VCL (TCustomActiveForm, я думаю) предоставляет дескриптор окна, который выдается ActiveX. Ваши компоненты VCL живут внутри TCustomActiveForm или потомка этого класса и никогда не знают разницы.

Возможно, вам удастся избежать накладных расходов ActiveX, если вы захотите сделать рытье и подъем. Сначала проверьте свойство ParentHwnd или метод CreateParented в TCustomForm. Это может быть все, что вам нужно - я не могу вспомнить свою голову, и прошло уже несколько лет с тех пор, как я увидел код.

Если нет, вы можете переопределить метод CreateParams в потоке потомков TCustomForm и назначить дескриптор окна без VCL в поле Params.WndParent. Сделайте это после вызова унаследованных CreateParams, чтобы вы получили все обычные настройки во всем остальном. Вы, вероятно, захотите изменить стиль и флаги exstyle, чтобы удалить границу формы, подпись и т. Д.

Постройте свой контроль VCL в этой пользовательской форме и поместите его в область всей формы.

Возможно, вы сможете сделать это с помощью более низкого уровня контроля, чем TCustomForm, например TCustomWinControl, но вы можете потерять обработку сообщений окна с нажатием клавиши/ускорителя. Я знаю, что это можно сделать на уровне TCustomForm.

4

да - если я понимаю ваш вопрос хорошо. Я выполнил полную программу установки без формы, визуального и визуального 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. 
+3

Вы неправильно поняли ОП. У него есть пользовательский контроль `TMyCustomControl`, который он хочет использовать. – 2010-12-04 14:46:28

+0

Его работа; хороший код и только 18 kb – VibeeshanRC 2010-12-04 14:48:43

3

Для VCL компонентов ответа явно да. Компоненты могут использоваться вне контекста формы без каких-либо хлопот, просто обходите механизм владения, указав nil и уничтожьте экземпляр вручную по окончании.

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

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

И я прошу вас, пожалуйста, прекратите смешение терминов формы и окно. (Дальнейшее чтение: верхние и дочерние окна)

0

Элемент управления может искать и получать доступ к свойствам в собственном и родительском контейнерах, обращаясь к ним как к классам VCL. Если это не так, есть хорошие шансы, что контроль VCL не будет работать.

Один из способов избежать этого - обернуть их как элементы управления ActiveX. Затем вы можете использовать его на любом языке, который поддерживает элементы управления ActiveX.

0

Это не только мой собственный код, но смеситель всех ваш код которым работали для меня

Просто добавьте этот код для вольвокса «s ответа (, который я принял, и на верхние)

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