CreateWindowsEx + Borland VCL + Beendet mein Programm nicht !
-
Hi,
ich bin durch verschiedene Umstände dazu gekommen ein eigenen Dialog-Fenster selbst erstellen zu wollen.
Ich habe bis jetzt im Borland Complier VCL programmiert was ich auch beibehalten werde.Jetzt geht es darum das ich ein eigens Fenster mit CreateWindowEx programmiere mit einen Button darauf.
Ich habe um es zum Anfang einfach zu halten einen TestDialog mit einem Button erstellt der einfach nur die Aufgabe haben soll meine VCL Application zu beenden.
Nur funktioniert das nicht die Anwendung wird nicht richtig beendet was auch immer ich versuche.
Beim compilieren wird die vorgegebene Form1 erstellt + Button (Drag&Drop).
Sobald ich diesen Button betätige öffnet sich mein eigenes Dialog-Fenster mit Button.
Meine Anwendung soll nun durch diesen Dialog beendet werden wenn ich auf den Button klicke. Leider tut Sie das nicht.#include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; #define BEENDEN 7 HINSTANCE ghInstance; //--------------------------------------------------------------------------- //Ereignisse für button LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch(msg) { case WM_COMMAND: switch(WPARAM(wParam)) { case 7: DestroyWindow(hwnd); Application->Terminate(); DestroyWindow(Form1->Handle); return 0; } case WM_DESTROY : PostQuitMessage(0); break; default : return( DefWindowProc( hwnd, msg, wParam, lParam )); } return( 0 ); } //int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow=8 ) bool BOXENDE(HWND HHwnd) { HWND HDialog, bBeenden; MSG msg ; WNDCLASSEX wc = {0}; ZeroMemory(&wc, sizeof wc); wc.cbSize = sizeof wc; wc.lpszClassName = TEXT( "TForm"); wc.hInstance = ghInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); wc.lpfnWndProc = WndProc; wc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_EXCLAMATION)); wc.lpszMenuName = 0; RegisterClassEx(&wc); HDialog = CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_TOPMOST | WS_EX_CONTROLPARENT, wc.lpszClassName, TEXT("Bestätigung"), WS_POPUP | WS_SYSMENU | WS_CAPTION, 100, 100, 200, 150, HHwnd, NULL, ghInstance, NULL); //CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_TOPMOST | WS_EX_CONTROLPARENT, "button", TEXT("Dialog Box"), //WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 10, 10, 50, 50, //HDialog, (HMENU)BEENDEN, ghInstance, NULL); bBeenden = CreateWindow("button", "Beenden", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 10, 10, 80, 30, HDialog, (HMENU)BEENDEN, ghInstance, NULL); // Find out if the window was created if( !HDialog ) // If the window was not created, return 0; // stop the application //Display the window to the user ShowWindow(HDialog, SW_SHOWNORMAL); // nCmdShow UpdateWindow(HDialog); // Decode and treat the messages // as long as the application is running while( GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { BOXENDE(this->Handle); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { }
-
Warum machst du dir das Leben so schwer? Du benutzt ja schon die VCL, dann kannst du auch den VCL Forms Designer benutzen und dein Fenster als eigene Klasse implementieren. Ist um einiges komfortabler als Fensterverwaltung mit der nackten Win32 API.
-
Ich weiss es nicht.
Weiss denn keiner weshalb sich mein Programm nicht beendet ?
-
Weil du hier in einer Message Loop steckst:
// Decode and treat the messages // as long as the application is running while( GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam;Dein 'Programm' ist ein Dialog/Fenster. Wenn du es schließen willst rufe bevor du BOXENDE aufrufst Hide() oder so auf. (k.A. was das bei der VCL ist)
-
Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum VCL (C++ Builder) verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Hi,
Leider weiss ich nicht an welcher Stelle ich Hide(); aufrufen soll.
Ich glaube auch das das sich dann auch nicht beendet.Ich habe mal den Code umgebaut, leider ist nun die Fensterprozedur etwas verkrüppelt. Nach langen hin und her testen läuft es jetzt einigermaßen.
Meine Datei - unit1.cpp
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; #define ID_BUTTON_ENDE 24 #define ID_BUTTON_CANCEL 0 HINSTANCE ghInstance; HFONT hf; HWND Button_1, Button_2, Static_1; //--------------------------------------------------------------------------- //Ereignisse für button LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: // WS_EX_DLGMODALFRAME | WS_EX_TOPMOST | WS_EX_CONTROLPARENT hf = CreateFont(14,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH, "ARIAL"); Button_1 = CreateWindowEx(WS_EX_TRANSPARENT, WC_BUTTON, ("N E I N"), WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_FLAT, 100, 60, 60, 23, hwnd, (HMENU)ID_BUTTON_CANCEL, ghInstance, 0); SendMessage(Button_1, WM_SETFONT, (WPARAM)hf, FALSE); Button_2 = CreateWindowEx(WS_EX_TRANSPARENT, WC_BUTTON, ("J A"), WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_FLAT, 30, 60, 60, 23, hwnd, (HMENU)ID_BUTTON_ENDE, ghInstance, 0); SendMessage(Button_2, WM_SETFONT, (WPARAM)hf, FALSE); hf = CreateFont(16,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH, "ARIAL"); Static_1 = CreateWindowEx(WS_EX_TRANSPARENT, "STATIC", TEXT("Programm beenden ?"), WS_CHILD | WS_VISIBLE, 27, 20, 142, 20, hwnd, 0, ghInstance, NULL); SendMessage(Static_1, WM_SETFONT, (WPARAM)hf, FALSE); break; case WM_COMMAND: //Command from Child windows and menus are under this message switch(wParam) //the ID is is wParam { case ID_BUTTON_CANCEL: EnableWindow(GetParent(hwnd), true); SetActiveWindow(GetParent(hwnd)); DestroyWindow(hwnd); return 0; } //case WM_DESTROY: /*2*/ //DestroyWindow(hwnd); //return 0; case ID_BUTTON_ENDE: PostQuitMessage(0); break; case WM_CLOSE: /*16*/ EnableWindow(GetParent(hwnd), true); SetActiveWindow(GetParent(hwnd)); DestroyWindow(hwnd); return 0; /* case WM_QUIT: return 0; */ default: return DefWindowProc(hwnd, msg, wParam, lParam); } //return 0; } //int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow=8 ) int BOXENDE(void *HHwnd) { MSG msg; WNDCLASSEX wndclass = {0}; wndclass.cbSize = sizeof( WNDCLASSEX ) ; wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = ghInstance ; //wndclass.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_QUESTION)); wndclass.hCursor = LoadCursor ( NULL, IDC_NO ); wndclass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = "TheDialogBox"; wndclass.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_QUESTION)); RegisterClassEx(&wndclass); RECT rc; GetWindowRect(HHwnd , &rc); int PosTop = rc.top + (rc.bottom - rc.top) / 2 - 65; int PosLeft = rc.left + (rc.right - rc.left) / 2 - 100; HWND HDialog = CreateWindowEx(WS_EX_TOPMOST, wndclass.lpszClassName, TEXT(" Bestätigung"), WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU, PosLeft, PosTop, 200, 130, HHwnd, NULL, ghInstance, NULL); // Find out if the window was created if( !HDialog ) // If the window was not created, return 0; // stop the application //Display the window to the user EnableWindow(HHwnd, false); ShowWindow(HDialog, SW_SHOWNORMAL); // nCmdShow UpdateWindow(HDialog); // Decode and treat the messages // as long as the application is running while( GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { BOXENDE(Form1->Handle); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { SetWindowPos(Form1->Handle, HWND_TOPMOST, 0, 0,0, 0, SWP_NOSIZE); }Ich bin wie gesgt damit nicht ganz zufrieden denn ich habe und musste den
ID_BUTTON_ENDE die ID 24 zuweisen, andere IDs führen zu misserfolgen in der
Fensterprozedur. Wie gesagt die Prozedur ist leider verkrüppelt aber für mein Vorhaben und das gewählte Fensterstyle sollte das ganze ausreichen. Ich weiss auch nicht genau für was eigentlich die 24 normalerweise steht würde mich aber eventuell dennoch interessieren.bis denne
-
Ich denke, die Frage gehört eigentlich nach WinAPI.
-
Dieser Thread wurde von Moderator/in akari aus dem Forum VCL (C++ Builder) in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Hi,
Endlich !!!
Ich habs geschafft !!!Die verkrüppelte Fensterprozedur ist Geschichte !!!
Der Fehler lag an der while Schleife die ich ja in meinem VCL gar nicht brauche denn
dort läuft doch bestimmt eine eigene, also habe ich diese nun herausgenommen,
und siehe da das Programm macht endlich das was es auch soll mit ordentlicher Fensterprozedur.Das kommt eben dabei heraus wenn man nur VCL programmiert,
man hat eigentlich keine Ahnung von C++.Datei unit1.h
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; #define ID_BUTTON_ENDE 1000 #define ID_BUTTON_CANCEL 0 HINSTANCE ghInstance; HFONT hf; HWND Button_1, Button_2, Static_1; //--------------------------------------------------------------------------- //Ereignisse für button LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: // WS_EX_DLGMODALFRAME | WS_EX_TOPMOST | WS_EX_CONTROLPARENT hf = CreateFont(14,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH, "ARIAL"); Button_1 = CreateWindowEx(WS_EX_TRANSPARENT, WC_BUTTON, ("N E I N"), WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_FLAT, 100, 60, 60, 23, hwnd, (HMENU)ID_BUTTON_CANCEL, ghInstance, 0); SendMessage(Button_1, WM_SETFONT, (WPARAM)hf, FALSE); Button_2 = CreateWindowEx(WS_EX_TRANSPARENT, WC_BUTTON, ("J A"), WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_FLAT, 30, 60, 60, 23, hwnd, (HMENU)ID_BUTTON_ENDE, ghInstance, 0); SendMessage(Button_2, WM_SETFONT, (WPARAM)hf, FALSE); hf = CreateFont(16,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH, "ARIAL"); Static_1 = CreateWindowEx(WS_EX_TRANSPARENT, "STATIC", TEXT("Programm beenden ?"), WS_CHILD | WS_VISIBLE, 27, 20, 142, 20, hwnd, 0, ghInstance, NULL); SendMessage(Static_1, WM_SETFONT, (WPARAM)hf, FALSE); break; case WM_COMMAND: //Command from Child windows and menus are under this message switch(wParam) //the ID is is wParam { case ID_BUTTON_CANCEL: EnableWindow(GetParent(hwnd), true); SetActiveWindow(GetParent(hwnd)); DestroyWindow(hwnd); break; case ID_BUTTON_ENDE: PostQuitMessage(0); break; } case WM_CLOSE: /*16*/ EnableWindow(GetParent(hwnd), true); SetActiveWindow(GetParent(hwnd)); DestroyWindow(hwnd); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } //int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow=8 ) int MeineBOX(void *HHwnd) { MSG msg; WNDCLASSEX wndclass = {0}; wndclass.cbSize = sizeof( WNDCLASSEX ) ; wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = ghInstance ; //wndclass.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_QUESTION)); wndclass.hCursor = LoadCursor ( NULL, IDC_NO ); wndclass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = "TheDialogBox"; wndclass.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_QUESTION)); RegisterClassEx(&wndclass); RECT rc; GetWindowRect(HHwnd , &rc); int BoxWidth = 200, BoxHeight = 130; int PosTop = rc.top + (rc.bottom - rc.top) / 2 - (BoxHeight/2); int PosLeft = rc.left + (rc.right - rc.left) / 2 - (BoxWidth/2); HWND HDialog = CreateWindowEx(WS_EX_TOPMOST, wndclass.lpszClassName, TEXT(" Bestätigung"), WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU, PosLeft, PosTop, BoxWidth, BoxHeight, HHwnd, NULL, ghInstance, NULL); // Find out if the window was created if( !HDialog ) // If the window was not created, return 0; // stop the application //Display the window to the user EnableWindow(HHwnd, false); ShowWindow(HDialog, SW_SHOWNORMAL); // nCmdShow UpdateWindow(HDialog); /* // Decode and treat the messages // as long as the application is running while( GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } */ return (int) msg.wParam; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { MeineBOX(Form1->Handle); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { SetWindowPos(Form1->Handle, HWND_TOPMOST, 0, 0,0, 0, SWP_NOSIZE); }
-
Gestalt schrieb:
Das kommt eben dabei heraus wenn man nur VCL programmiert,
man hat eigentlich keine Ahnung von C++.Was hat jetzt das Wissen über ein Framework mit dem Wissen über einer Programmiersprache zu tun? Diese Aussage zeugt eigentlich nur von einer weiteren Unwissenheit deinerseits.
Des weiteren ist es selten eine gute Idee VCL und reine WinAPI zu mischen. Worin besteht eigentlich der Sinn, wenn du schon die VCL nutz, ein Fenster ohne VCL erstellen zu wollen?
-
Ok dann werd ich mal versuchen Dir das zu erklären.
Als erstes Lade Dir mal das Programm Filemon auf Deine Kiste, gute Kisten haben das natürlich längst drauf.
Dann startest Du mal das Ding.
Nun gehst Du oben im Reiter auf Optionen und klickst auf "Always On Top"
und wenn Du das geschafft klickst Du im Reiter Help auf "About...".So nun hast Du 2 Fenster im Vordergrund deines Desktops egal was Du nun betätigst und wie oft (in der Taskleiste oder sonst wo du umherklickst) beide Fenster bleiben im Vordergrund ! Ja und genau das ist eigentlich mein Problem mit Borland VCL bekomme ich das nicht gebacken !
Ich habe das mit CreateWindowEx nachgebaut und es funktioniert.
Beide Fenster müssen mit CreateWindowsEx erzeugt werden was ich mit VCL nicht hinkriege. Es liegt am Hauptfenster welches ich nicht so eingestellt bzw. manipuliert bekomme das es wie ein mit CreateWindowsEx erzeugtes Fenster reagiert !Und ich behaupte trotzdem wer VCL programmiert (auch ich) hat keine Ahnung !
bis denne
-
Hallo,
so habs jetzt auch mit VCL hinbekommen sodaß 2 Fenster im Vordergrund stehen.
Es klappt sogar mit der Funktion ShowModal() zum anzeigen des zweiten fensters
obwohl ich desöfteren gelesen habe es ginge nur mit CreateWindowEx
und ShowModal wäre da sowieso fehl am Platze und auch ich irgendwann davon überzeugt war.Ich poste hier mal den Code des 2ten Fensters er ist eigentlich sehr Simpel
sobald das 2 Fenster angezeigt wird steht die gesamte Application im Vordergrund.
Öffnet das 2te Fenster mit Form2->ShowModal();.
(ja ich weiss kein WinApi)Fenster 2 (unit1.cpp)
#include <vcl.h> #pragma hdrstop #include "Unit2.cpp" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm2 *Form2; //--------------------------------------------------------------------------- __fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm2::FormShow(TObject *Sender) { SetWindowPos(Application->Handle, HWND_TOPMOST, Left,Top, Width, Height, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); }Fenster 2 (unit2.h)
#ifndef Unit2H #define Unit2H //--------------------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //--------------------------------------------------------------------------- class TForm2 : public TForm { __published: // Von der IDE verwaltete Komponenten TButton *Button1; void __fastcall FormShow(TObject *Sender); private: // Anwender-Deklarationen protected: void __fastcall CreateParams(TCreateParams &Params) { TForm::CreateParams(Params); Params.WndParent = Application->MainForm->Handle; } public: // Anwender-Deklarationen __fastcall TForm2(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm2 *Form2; //--------------------------------------------------------------------------- #endif