Oeffnen-Dialog erscheint nicht
-
Was habe ich falsch gemacht (habe auch versucht return 0; einzufuegen, da das auch schon der Fehler war)? Der Oeffnen-Dialog sollte bei Klick auf den Button erscheinen:
#include <windows.h> #include <commdlg.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); const char szAppName[] = "Ein eigenes Fenster mit Text und Button"; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hWnd; MSG msg; WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszClassName = szAppName; wc.lpszMenuName = NULL; RegisterClass(&wc); hWnd = CreateWindow(szAppName, "Titelleiste :-p", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, /* X-Position auf dem Monitor */ CW_USEDEFAULT, /* Y-Position auf dem Monitor */ CW_USEDEFAULT, /* Fensterbreite */ CW_USEDEFAULT, /* Fensterhoehe */ NULL, NULL, hInstance, NULL); ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hButton; //Buttons static HWND hButton2; switch (message) { case WM_CREATE: //Buttons { hButton = CreateWindow( "button", "juhee :-D", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); hButton2 = CreateWindow( "button", "Beenden", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL); return 0; } case WM_SIZE: { MoveWindow(hButton, LOWORD(lParam) / 2 - 80, HIWORD(lParam) - 30, 160, 22, TRUE); MoveWindow(hButton2, LOWORD(lParam) / 2 - 80, HIWORD(lParam) - 60, 160, 22, TRUE); return 0; } case WM_COMMAND: { if (lParam == (LPARAM)hButton) { if (HIWORD(wParam) == BN_CLICKED) { OPENFILENAME ofn; // common dialog box structure char szFile[260]; // buffer for file name HWND hwnd; // owner window HANDLE hf; // file handle // Initialize OPENFILENAME ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFile = szFile; // // Set lpstrFile[0] to '\0' so that GetOpenFileName does not // use the contents of szFile to initialize itself. // ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = sizeof(szFile); ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0"; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; // Display the Open dialog box. if (GetOpenFileName(&ofn)==TRUE) hf = CreateFile(ofn.lpstrFile, GENERIC_READ, 0, (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); } } if (lParam == (LPARAM)hButton2) //Button2 { if (HIWORD(wParam) == BN_CLICKED) MessageBox (0, "Chasch denn guet klicke", "Super! ", 64); int Antwort=MessageBox (0, "Zuemache !?", "Super! ",MB_ICONERROR| MB_YESNO); { if (IDYES==Antwort) MessageBox (0, "Denn halt :-p", "OK", MB_ICONWARNING); } if (IDYES==Antwort) { SendMessage(hWnd, WM_CLOSE, 0, 0); } } return 0; } case WM_PAINT: //Text { PAINTSTRUCT ps; HDC hDC; const char szText[] = "Hallo, dies ist der Text."; const char szText2[]="Das isch nomol e Text!!!"; hDC = BeginPaint(hWnd, &ps); { TextOut(hDC, 50, 50, szText, sizeof(szText) - 1); TextOut (hDC, 90, 90, szText2, sizeof(szText2) -1); } EndPaint(hWnd, &ps); return 0; // ENDE neu Text } case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hWnd, message, wParam, lParam); }
-
Das Handle des "Owner-Windows" vom Oeffnen-Dialog ist nicht korrekt :
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { ... HWND hwnd; // ofn.hwndOwner = hwnd; ofn.hwndOwner = hWnd; ... }
-
also erstens:
es wäre wesentlich übersichtlicher gewesen, wenn du nur gepostet hättest, worauf es ankommt:
// ... OPENFILENAME ofn; // common dialog box structure char szFile[260]; // buffer for file name HWND hwnd; // owner window HANDLE hf; // file handle // Initialize OPENFILENAME ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFile = szFile; // // Set lpstrFile[0] to '\0' so that GetOpenFileName does not // use the contents of szFile to initialize itself. // ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = sizeof(szFile); ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0"; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; // Display the Open dialog box. if (GetOpenFileName(&ofn)==TRUE) hf = CreateFile(ofn.lpstrFile, GENERIC_READ, 0, (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); // ...zweitens:
wer ab und zu in die MSDN guckt, weiß, dass OFN_FILEMUSTEXIST OFN_PATHMUSTEXIST beinhaltet.
also ist das OFN_PATHMUSTEXIST sinnlos.und drittens (das wichtigste zum Schluss^^):
Microsoft lässt dir die Möglichkeit ein eigenes Dialogtemplate zu nutzen.
also mache Windows erst klar, dass du den Standard-Dialog willst.
ich mach das immer so:// ... OPENFILENAME ofn; ofn.dwReserved = 0; ofn.Flags = OFN_ENABLESIZING|OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_LONGNAMES; ofn.FlagsEx = 0; ofn.hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWL_HINSTANCE); ofn.hwndOwner = g_hFrameWnd; ofn.lCustData = NULL; ofn.lpfnHook = 0; ofn.lpstrCustomFilter = NULL; ofn.lpstrDefExt = "TXT"; PFileName pFN = (PFileName)GetWindowLongPtr(hWnd, GWLP_USERDATA); char szFileName[MAX_PATH]; if (pFN != NULL) strncpy_s(szFileName, MAX_PATH, pFN->szFileName, MAX_PATH); else szFileName[0] = '\0'; ofn.lpstrFile = szFileName; ofn.lpstrFileTitle = NULL; ofn.lpstrFilter = "Textdateien (*.txt)\0*.txt\0Alle Dateien\0*.*\0\0"; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = NULL; ofn.lpTemplateName = NULL; ofn.lStructSize = sizeof(OPENFILENAME); ofn.nFileExtension = 0; ofn.nFileOffset = 0; ofn.nFilterIndex = 0; ofn.nMaxCustFilter = 0; ofn.nMaxFile = MAX_PATH; ofn.nMaxFileTitle = 0; ofn.pvReserved = NULL; if (GetOpenFileName(&ofn) != FALSE) // ...das stammt aus einem Texteditor mit MDI von mir.
da fällt mir gleich noch was auf:
man überprüft NIE, ob etwas gleich TRUE ist.
denn FALSE wird IMMER als 0 definiert.
TRUE ist jedoch != 0 und damit undefiniert.
Es ist somit dem Compilerhersteller, oder bei der WinAPI Microsoft überlassen, welchen Wert TRUE hat.
Wenn man aber überprüft, ob etwas ungleich FALSE ist, so ist man immer auf der sicheren Seite.MfG DrakoXP
PS.:
merker muss ich auch Recht geben.
lass dasHWND hwnd;weg und schreib
ofn.hwndOwner = hWnd;denn das Handle bekommst du ja als Parameter und somit brauchst du nicht extra eine neue Handle-Variable deklarieren, die nichtmal einen definierten Wert besitzt.
-
Ach so! Danke!
Lustigerweise ist der Ausschnitt aus der MSDN.
-
DrakoXP schrieb:
da fällt mir gleich noch was auf:
man überprüft NIE, ob etwas gleich TRUE ist.
denn FALSE wird IMMER als 0 definiert.
TRUE ist jedoch != 0 und damit undefiniert.
Es ist somit dem Compilerhersteller, oder bei der WinAPI Microsoft überlassen, welchen Wert TRUE hat.
Wenn man aber überprüft, ob etwas ungleich FALSE ist, so ist man immer auf der sicheren Seite.Nicht wirklich, oder? Das kann doch nicht sein, dass die solche Fallen einbauen.
-
naja, soweit ich weiß, definiert Microsoft TRUE als -1, aber sicher ist halt sicher.
denn wenn du in der MSDN liest, z.B. bei
BOOL UpdateWindow( HWND hWnd // handle to window );dann liest man da:
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.und nonzero heißt bei mir ungleich 0 und nicht -1.
also lieber mit FALSE überprüfen, anstatt mit TRUE.
-
DrakoXP schrieb:
also lieber mit FALSE überprüfen, anstatt mit TRUE.
Man sollte IMHO diese Konstanten in bool-Ausdrücken gar nicht benutzen.
if( foo == TRUE )ist genauso überflüssig wie
if( foo != FALSE )Einfach nur:
if( foo )-> Fertig.
-
ähm, vielleicht hast du übersehen, dass es keine bool-Ausdrücke sind,
sondern BOOL-Ausdrücke, und BOOL ist von Microsoft als int definiert.deshalb kann man BOOL auch nich einfach zu bool casten.
jedenfalls nicht ohne den Hinweis auf einen Datenverlust...
-
DrakoXP schrieb:
ähm, vielleicht hast du übersehen, dass es keine bool-Ausdrücke sind,
sondern BOOL-Ausdrücke, und BOOL ist von Microsoft als int definiert.Nein, das habe ich nicht übersehen.
deshalb kann man BOOL auch nich einfach zu bool casten.
jedenfalls nicht ohne den Hinweis auf einen Datenverlust...Die Verwendung eines int-Ausdrucks in einer if-Anweisung erzeugt bei keinem mir bekannten Compiler einen "Hinweis auf einen Datenverlust". Hast du ein Beispiel?
-
ja, in diesem Fall geht es^^
der Hinweis sollte kommen bei bei
BOOL x = TRUE; bool y = (bool)x;im Endeffekt geht das trotzdem, aber halt Warnung...
-
Nein! Auch in diesem Fall kommt keine Warnung. Denn Du führst einen cast aus. Un der cast von int auf bool ürt nichts anderes aus als ein das Ergebnis von x!=0 zu setzen.
Eine Warnung kommt nur, wenn Du du Zuweisung ohne cast ausführst.
-
Martin Richter schrieb:
Eine Warnung kommt nur, wenn Du du Zuweisung ohne cast ausführst.
C4800 kommt auch bei einem Cast:
MSDN Library schrieb:
Casting the expression to type bool will not disable the warning, which is by design.
-
Upps...
Ja es kommt eine Warnung, aberist ist keine Warnung über Datenverlust! Es ist eine Performance Warnung!Aber Ok! Ganz korrekt war meine Antwort nicht.
Dann ist der korrekte Weg einzig und alleine
BOOL x = TRUE; bool y = x!=0;
-
Jedenfalls funktioniert es bei mir nun ordentlich; wegen der Prüfung, müsste mal jedes Szenario ausprobieren.
Gibt es eine andere Möglichkeit auf den Dateinamen zuzugreifen als ofn.lpstrFile ?Vielen Dank
-
Was meinst Du mit andere Möglichkeiten?
-
Anstelle z.B. MessageBox (ofn.lp..... ...) den namen in einem normalen Char oder string zu haben
-
lpstrFile ist ein normaler TCHAR*, was möchtest Du mehr?
-
Ja ein Zeiger oder irre ich mich da? Den Wert in einrm "normalen" char, nicht als Zeiger
-
APIAnfaenger schrieb:
Ja ein Zeiger oder irre ich mich da? Den Wert in einrm "normalen" char, nicht als Zeiger
Es ist ein Zeiger! TCHAR ist entweder char oder wchar_t je nach Zeichensatz.
BTW:DrakoXP schrieb:
TRUE ist jedoch != 0 und damit undefiniert.
Natürlich ist TRUE definiert und zwar als 1 -sinnigerweise.
DrakoXP schrieb:
Es ist somit dem Compilerhersteller, oder bei der WinAPI Microsoft überlassen, welchen Wert TRUE hat.
Ein Compilerhersteller hat damit wenig zu tun, da diese nicht im Compiler (bzw. in der entsprechenden Sprache) verankert sind, im Gegensatz zu (bspw.) true oder false. Damit ist es also nur Microsoft überlassen, welchen Wert diese Konstanten wirklich haben, und der steht in den Headern.
q.e.d.:windef.h [WinApi-Standardheader] schrieb:
// ...
#ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif// ...
-
Soweit ich den Standard im Kopf habe ist das Ergebnis von 1==1 definiert als true, 1!=0 als false. Weißt man ein boolsches Ergebnis einer int Variable zu ist dies definiert als 1 oder 0.
Richtig ist, dass die interne Darstellung eines bool Datatypes dem Compilerhersteller überlassen ist.
Die Zuweisung in einen int ist keineswegs undefiniert.
Insofern ist es nur zu logisch 0 als FALSE und 1 als TRUE zu definieren.Unterscheiden muss man dennoch die Nutzung des Datentypes BOOL in der WinAPI. Hier gilt nur folgendes hat ein BOOL Typ den Wert 0, heißt dies false. !=0 bedeutet false. Man kann aber eben nicht mit Sicherheit sagen, dass TRUE returniert wird. Die Ergebnisse 5, 1234 und so weiter würden ebenfalls true signalisieren.
Der Vergleich eines BOOL Wertes mit TRUE führt also nicht unbedingt zum gewünschten Ergebnis. Der Vergleich eines BOOL Wertes mit FALSE dagegen schon...Ich hoffe das ist verständlich.
-
Martin Richter schrieb:
[...]
Ich hoffe das ist verständlich.Joar klaro
. Damit sollte man damit doch auf der richtigen Seite sein:BOOL bSuccess = IrgendEineFunktionDieBOOLZurueckGibt(); if(bSuccess) // Erfolgreich... else // Aua...(Bereits von MFK gepostet; diese Prüfung bevorzuge ich nämlich auch.)