Anfänger - Programm funktioniert, aber....
-
hier der komplette code, so wie er JETZT nach div korrekturen dasteht (dank eurer hilfe - geile sache!! bin total dankbar)
#include <tchar.h> #include <windows.h> #include <stdlib.h> #include <stdio.h> #include<cstring> #include <vector> #define FILE_MENU_NEW 1 #define FILE_MENU_OPEN 2 #define FILE_MENU_SAVE 3 #define FILE_MENU_EXIT 4 #define GENERATE_BUTTON 5 #define OPEN_FILE_BUTTON 6 #define SAVE_FILE_BUTTON 7 #define FILE_MENU_INFO 8 using namespace std; using std::vector; LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); void AddMenus(HWND); void AddControls(HWND); void loadImages(); void registerDialogClass(HINSTANCE); void displayDialog(HWND); HWND hName,hAge,hOut,hLogo, hMemo; HMENU hMenu; HBITMAP hLogoImage, hGenerateImage; int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow) { WNDCLASSW wc = {0}; wc.hbrBackground = (HBRUSH)COLOR_WINDOW ; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hInstance = hInst; wc.lpszClassName = L"myWindowClass"; wc.lpfnWndProc = WindowProcedure; if (!RegisterClassW(&wc)) return -1; registerDialogClass(hInst); CreateWindowW(L"myWindowClass", L"My Window", WS_OVERLAPPEDWINDOW|WS_VISIBLE,0,0,900,600,NULL,NULL,NULL,NULL); MSG msg ={0}; while ( GetMessageW(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } void display_file(const char* path) { FILE *file = fopen(path,"rb"); fseek(file,0,SEEK_END); int _size = ftell(file); rewind(file); std::vector<char> data(_size+1); fread(data.data(),_size,1,file); SetWindowTextA(hMemo,data.data()); fclose(file); } void openFile(HWND hwnd) { OPENFILENAME ofn; char file_name[100]; ZeroMemory(&ofn,sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hwnd; ofn.lpstrFile = file_name; ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = 100; ofn.lpstrFilter = "All Files\0*.*\0Text Files\0*.TXT\0"; ofn.nFilterIndex =1; GetOpenFileName(&ofn); if(GetOpenFileName(&ofn)) display_file(ofn.lpstrFile); } void write_file(char* path) { FILE *file = fopen(path,"w"); int _size = GetWindowTextLength(hMemo); char *data = new char[_size+1]; GetWindowText(hMemo,data,_size+1); fwrite(data,_size+1,1,file); fclose(file); } void save_file(HWND hwnd) { OPENFILENAME ofn; char file_name[100]; ZeroMemory(&ofn,sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hwnd; ofn.lpstrFile = file_name; ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = 100; ofn.lpstrFilter = "All Files\0*.*\0Text Files\0*.TXT\0"; ofn.nFilterIndex =2; GetSaveFileName(&ofn); if(GetSaveFileName(&ofn)) // Returnwert prüfen? write_file(ofn.lpstrFile); } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int val; switch (message) { case WM_COMMAND: switch(wParam) { case FILE_MENU_NEW: MessageBeep(MB_OK); break; case FILE_MENU_OPEN: openFile(hwnd); break; case FILE_MENU_SAVE: save_file(hwnd); break; case FILE_MENU_INFO: displayDialog(hwnd); break; case SAVE_FILE_BUTTON: save_file(hwnd); break; case FILE_MENU_EXIT: val = MessageBoxW(hwnd, L"Are you sure?",L"Wait", MB_YESNO| MB_ICONEXCLAMATION); if(val==IDYES) { DestroyWindow(hwnd); } else { // do nothing } break; case GENERATE_BUTTON: char name[30], age[10], out[50]; GetWindowText(hName, name,30); GetWindowText(hAge, age,10); if(strcmp(name,"")==0 || strcmp(age,"")==0) { val = MessageBoxW(hwnd, L"You did enter nothing", NULL, MB_ABORTRETRYIGNORE|MB_ICONERROR); switch(val) { case IDABORT: DestroyWindow(hwnd); break; case IDRETRY: return 0; break; case IDIGNORE: break; } } strcpy(out, name); strcat(out, " is "); strcat(out, age); strcat(out, " Years old "); SetWindowText(hOut,out); break; } break; case WM_CREATE: // Loads the Content in Created Window loadImages(); // images MUST ALWAYS be loaded BEFORE controls!! AddMenus(hwnd); AddControls(hwnd); break; case WM_DESTROY: PostQuitMessage (0); // send a WM_QUIT to the message queue */ break; default: return DefWindowProc (hwnd, message, wParam, lParam); case WM_KEYDOWN: if( wParam == VK_ESCAPE ){ if(MessageBox(0, "Are you sure you want to exit?", "Really?", MB_YESNO | MB_ICONQUESTION) == IDYES) DestroyWindow(hwnd); } } return 0; } void AddMenus(HWND hwnd) { hMenu = CreateMenu(); HMENU hFileMenu1 = CreateMenu(); HMENU hFileMenu2 = CreateMenu(); HMENU hSubMenu1 = CreateMenu(); HMENU hSubMenu2 = CreateMenu(); // first menu row AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu1,"File"); AppendMenu(hFileMenu1, MF_STRING,FILE_MENU_NEW, "New"); AppendMenu(hFileMenu1, MF_POPUP,FILE_MENU_OPEN, "Open File"); AppendMenu(hFileMenu1, MF_POPUP,(UINT_PTR)hSubMenu2 , "Open Submenu 2"); AppendMenu(hFileMenu1, MF_STRING,FILE_MENU_SAVE, "Save"); AppendMenu(hFileMenu1, MF_SEPARATOR, NULL, NULL); AppendMenu(hFileMenu1, MF_STRING,FILE_MENU_EXIT, "Exit"); // the sub menus for 1 row AppendMenu(hSubMenu1, MF_STRING,NULL, "Sub Menu Item 1"); AppendMenu(hSubMenu1, MF_STRING,NULL, "Sub Menu Item 2"); AppendMenu(hSubMenu2, MF_STRING,NULL, "Sub Menu Item 1"); AppendMenu(hSubMenu2, MF_STRING,NULL, "Sub Menu Item 2"); // second menu row AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu2,"Options"); AppendMenu(hFileMenu2, MF_STRING,NULL, "Options"); // third menu row AppendMenu(hMenu, MF_STRING, FILE_MENU_INFO,"Info"); SetMenu(hwnd, hMenu); } void AddControls(HWND hwnd) { CreateWindowW(L"STATIC", L"Name:", WS_VISIBLE|WS_CHILD,100,55,98,38,hwnd,NULL,NULL,NULL); hName = CreateWindowW(L"EDIT", L"", WS_VISIBLE|WS_CHILD | WS_BORDER,200,50,98,25,hwnd,NULL,NULL,NULL); CreateWindowW(L"STATIC", L"Age:", WS_VISIBLE|WS_CHILD,100,85,98,38,hwnd,NULL,NULL,NULL); hAge = CreateWindowW(L"EDIT", L"", WS_VISIBLE|WS_CHILD | WS_BORDER,200,80,98,25,hwnd,NULL,NULL,NULL); // Orig Button //HWND hBut = CreateWindowW(L"BUTTON", L"Generate", WS_VISIBLE|WS_CHILD | WS_BORDER,100,120,98,25,hwnd,(HMENU)GENERATE_BUTTON,NULL,NULL); // Img Button HWND hBut = CreateWindowW(L"BUTTON", NULL, WS_VISIBLE|WS_CHILD|BS_BITMAP,100,120,98,25,hwnd,(HMENU)GENERATE_BUTTON,NULL,NULL); SendMessageW(hBut, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hGenerateImage); CreateWindowW(L"BUTTON", L" Entry Data ", WS_VISIBLE|WS_CHILD | BS_GROUPBOX,20,10,450,230,hwnd,NULL,NULL,NULL); hOut = CreateWindowW(L"EDIT", L"", WS_VISIBLE|WS_CHILD | WS_BORDER,40,160,400,30,hwnd,NULL,NULL,NULL); hLogo = CreateWindowW(L"STATIC", NULL, WS_VISIBLE|WS_CHILD|SS_BITMAP,500,20,367,300,hwnd,NULL,NULL,NULL); SendMessageW(hLogo, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hLogoImage); // teil 3 - open dialog etc hMemo = CreateWindowW(L"EDIT", L"...", WS_VISIBLE|WS_CHILD|WS_BORDER|ES_MULTILINE|WS_VSCROLL|WS_HSCROLL,20,250,450,250,hwnd,NULL,NULL,NULL); CreateWindowW(L"BUTTON", L" Save ", WS_VISIBLE|WS_CHILD,500,450,100,50,hwnd,(HMENU)SAVE_FILE_BUTTON,NULL,NULL); } void loadImages() { hLogoImage = (HBITMAP)LoadImageW(NULL, L"img\\randy1.bmp", IMAGE_BITMAP, 367, 300, LR_LOADFROMFILE); hGenerateImage = (HBITMAP)LoadImageW(NULL, L"img\\b_button.bmp", IMAGE_BITMAP, 98,25, LR_LOADFROMFILE); } LRESULT CALLBACK DialogProcedure(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) { switch(msg) { case WM_COMMAND: switch(wp) { case 1: DestroyWindow(hwnd); break; } break; case WM_CLOSE: DestroyWindow(hwnd); break; default: return DefWindowProcW(hwnd,msg,wp,lp); } } void registerDialogClass(HINSTANCE hThisInstance) { WNDCLASSW dialog = {0}; dialog.hbrBackground = (HBRUSH)COLOR_WINDOW; dialog.hCursor = LoadCursor(NULL,IDC_CROSS); dialog.hInstance = hThisInstance; dialog.lpszClassName = L"myDialogClass"; dialog.lpfnWndProc = DialogProcedure; RegisterClassW(&dialog); } void displayDialog(HWND hwnd) { HWND hDlg = CreateWindowW(L"myDialogClass", L"Info",WS_VISIBLE|WS_OVERLAPPEDWINDOW, 400,400,300,300,(hwnd),NULL,NULL,NULL); CreateWindowW(L"BUTTON",L"Close",WS_VISIBLE|WS_CHILD,80,180,100,28,hDlg, (HMENU)1,NULL,NULL); CreateWindowW(L"STATIC",L"Info\n\nMy First Win32 Program\nWritten in C++",WS_VISIBLE|WS_CHILD,20,20,300,300,hDlg, (HMENU)1,NULL,NULL); }
-
@peroja sagte in Anfänger - Programm funktioniert, aber....:
GetOpenFileName(&ofn); if(GetOpenFileName(&ofn)) display_file(ofn.lpstrFile);
Du darfst natürlich nur einmal
GetOpenFileName(&ofn)
aufrufen (gilt analog auch fürGetSaveFileName(&ofn)
)!!!PS: Wegen Warnungen s. Einstellungen für Code::Blocks ("Compiler-Flags einstellen")
-
@yahendrik Ah ja besten Dank, ja dass ich mit Unicode das kompilieren wollte war natürlich ein grober Schnitzer.
-
Du darfst natürlich nur einmal
GetOpenFileName(&ofn)
aufrufen (gilt analog auch fürGetSaveFileName(&ofn)
)!!!Ja klar... autsch jetzt wo es ... oh mann (peinlich)
ok, hab ne faire aurede: ich hab erst vor ca 2 wochen angefangen mit C++ und bin aber etwa 3std. am tag dabei
-
nextsteps:
1)
ich versuche herauszufinden wie ich PNG und JPG anstelle BMP images einbinden kann. (nicht so wichtig)ich erzeuge ein modalfenster mit checkbox, radio und ein select dropdown und speichere die values in ein txt file.
dieses soll beim nächsten aufruf des modals wieder gelesen werden und die checkbox, radio und select mit den entsprechenden values wieder geladen werden. (ein versuch später ein config file zu basteln)ich geh mal davon aus dass ich fopen() und fread() auch ohne dialogfenster nutzen kann....
ich versuche erst mal und wenns nicht klappt frage ich.
-
@peroja sagte in Anfänger - Programm funktioniert, aber....:
ich nutze die IDE CODEBLOCKS
Selber schuld.
Ne, ernsthaft? Vergiss die WinAPI und lern' erstmal C++.
-
@Swordfish ganz bestimmt werd ich das tun nur weil DU es sagst. ironieoff
ich hab anständig gefragt und auch anständig geantwortet. und was ist an CODE::BLOCKS so schlimm?
ich hab es eben jetzt als meine IDE zum lernen gewählt und nicht VS , obwohl ich das auch hab.
wenn du mir beim lernen helfen willst dann dankeschön. wenn nicht, dann geh bitte wo anders stänkern. bei mir funzt sowas nicht.
-
@peroja sagte in Anfänger - Programm funktioniert, aber....:
wenn nicht, dann geh bitte wo anders stänkern.
ok
// edit: Heck, alleine schon an dem Code oben sieht man wie viel blödsinn Du Dir mit der WinAPI "beibringst". Aber ist ja Dein Bier. Wer nicht hören will ...
-
@peroja sagte in Anfänger - Programm funktioniert, aber....:
while ( GetMessageW(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
ist übrigens kaput.
-
/ edit: Heck, alleine schon an dem Code oben sieht man wie viel blödsinn Du Dir mit der WinAPI "beibringst". Aber ist ja Dein Bier. Wer nicht hören will ...
ja? wirklich? weil du seit einigen jahren codest und sicher mehr erfahrung hast als einer der grad mal 2 wochen dabei ist, bedeutet für dich dass du mich von oben herab behandeln kannst? bevor du einen auf lehrer machst, lern gefälligst etwas anstand und respekt. du hast auch mal angefangen.
auch wenn du recht hast und mein code vielleicht nicht optimal ist, anstatt zu kritisieren kannst du mir freundlich zeigen WO ich WAS falsch mache und erklären warum was wie ist. die anderen konnten es doch auch, oder?
im übrigen bin ich einem tutorial von einem inder gefolgt. wenn mein kompiler meinen code zwar mit warnungen kompiliert und die exe dann auch macht was sie soll, wie soll ich wissen dass ich etwas falsch mache? ich bin totaler anfänger. und C++ konsolensachen hab ich übrigens n ganzen monat gebastelt und die grundsachen kennen zu lernen. aus einem buch "Grundkurs C" von Jürgen Wolfalso... mein code ist "kaputt", kann sein. sag mir bitte (freundlich) was kaputt ist und weshalb. und wenn du mir ein beispiel geben könntest wie man es richtig macht, dann wäre ich sogar dankbar und hätte, stell dir mal vor, etwas von dir gelernt.
-
Hör bitte auf mit dieser trotzigen Art.
Globale Variablen sind gaga und schau Dir an was
GetMessage()
zurückgibt.@peroja sagte in Anfänger - Programm funktioniert, aber....:
aus einem buch "Grundkurs C" von Jürgen Wolf
Ja, wegwerfen. (Kannst auch freundlich wegwerfen und dabei lächeln, aber bitte wegwerfen.)
-
@Swordfish sagte in Anfänger - Programm funktioniert, aber....:
Hör bitte auf mit dieser trotzigen Art.
Globale Variablen sind gaga und schau Dir an was
GetMessage()
zurückgibt.hab ich jetzt mal nachgesehen und da hat jemand das ganze etwas anders geschrieben. hab ich kopiert und funzt
while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); }
ich versteh es aber nicht was du meinst mit GetMessage() ausgabe? was soll es zurückgeben? und wo sehe ich das?
@peroja sagte in Anfänger - Programm funktioniert, aber....:
aus einem buch "Grundkurs C" von Jürgen Wolf
Ja, wegwerfen. (Kannst auch freundlich wegwerfen und dabei lächeln, aber bitte wegwerfen.)
du kennst das buch? so schlimm? nun ja ich kann das nicht beurteilen. die beispiele machen für mich (als rookie) sinn.
-
@peroja sagte in Anfänger - Programm funktioniert, aber....:
hab ich kopiert und funzt
Ja, so funktioniert C++ nicht.
@peroja sagte in Anfänger - Programm funktioniert, aber....:
ich versteh es aber nicht was du meinst mit GetMessage() ausgabe? was soll es zurückgeben? und wo sehe ich das?
@peroja sagte in Anfänger - Programm funktioniert, aber....:
du kennst das buch? so schlimm?
Ich kenne den Autor. Schlimm genug.
-
und siehst du auf die schnelle wo ich den fehler mit dem window titel mache? da kommt nur M anstatt My Window
-
die beste art für mich zu lernen ist wenn jemand meinen code korrigiert und // kommentiert
kompiliert und testets und danach postet.ich weiss ist viel verlangt, aber für mich die ideale art zu lernen, weill dann sehe ich was ich falsch gemacht habe
mann kan ja meine zeilen auch auskommentieren und neu schreiben. dann sehe ich den unterschied
-
@peroja sagte in Anfänger - Programm funktioniert, aber....:
die beste art für mich zu lernen ist wenn jemand meinen code korrigiert und // kommentiert
kompiliert und testets und danach postet.ich weiss ist viel verlangt, aber für mich die ideale art zu lernen, weill dann sehe ich was ich falsch gemacht habe
mann kan ja meine zeilen auch auskommentieren und neu schreiben. dann sehe ich den unterschied
Die beste Art wäre, vernünftig anzufangen mit C wenn du alte WinApi programmieren möchtest.
Für C++ gibt es Wrapper wie wxWidgets, Qt, oder alterndes MFC den WinApi32 ist alles andere als C++ und die Basics solltest du schon können bevor du mit Winapi rumhandtierst.mFg Ara
ps: jeder hat mal angefangen doch ohne grundlagen landest du mit jedem code hier
-
@peroja sagte in Anfänger - Programm funktioniert, aber....:
und siehst du auf die schnelle wo ich den fehler mit dem window titel mache? da kommt nur M anstatt My Window
Ich würds mal auf das Mischen der A- und W-Varianten und damit char und wchar_t schieben. WinMain etwas umgeschrieben:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow) { WNDCLASS wc = {0}; wc.hbrBackground = (HBRUSH)COLOR_WINDOW ; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hInstance = hInst; wc.lpszClassName = TEXT("myWindowClass"); wc.lpfnWndProc = WindowProcedure; if(!RegisterClass(&wc)) return -1; registerDialogClass(hInst); CreateWindow(TEXT("myWindowClass"), TEXT("My Window"), WS_OVERLAPPEDWINDOW|WS_VISIBLE,0,0,900,600,NULL,NULL,NULL,NULL); MSG msg ={0}; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }
SetWindowText/GetWindowText/AppendMenu solte ebenfalls das A rangestellt werden, wenn du mit chars arbeitest. Wie geschrieben, besser wäre es natürlich auf TCHARs umzustellen (siehe oben).
Und die Messageloop ist völlig okay, wenn weder ein Windowhandle noch ein Rangefilter angegeben wurde. Siehe hier.
-
@peroja sagte in Anfänger - Programm funktioniert, aber....:
[sinngemäß] schreib meinen code um und versehe ihn mit Kommentaren.
Sonst geht es Dir noch halbwegs gut?
@peroja sagte in Anfänger - Programm funktioniert, aber....:
also... mein code ist "kaputt"
Ja. Lies die verdammte Dokumentation.
@yahendrik sagte in Anfänger - Programm funktioniert, aber....:
while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
ist immer noch kaput.
-
@peroja: Ich sehe auch das Mischen von ANSI und WideString als das Problem an.
Hier ein paar (englische) Artikel dazu:- WinAPI: Being Unicode Friendly
- Code::Blocks: Unicode
- Lessons in Windows API programming (C++) - Lesson 2: The API is based on Unicode
Du solltest also (bei WinAPI-Projekten) immer mit "UNICODE" kompilieren (außer du willst noch für Win98 kompilieren ;- )
Und generell auf die explizite Angabe vonA
undW
verzichten und, wie schon geschrieben, String-Literale mit dem_T
- oderTEXT
-Makro benutzen. Und dannTCHAR
als Datentyp (anstatt explizitchar
oderwchar_t
).
-
Hallo,
Ich hab mich natürlich nicht Ermutigen lassen und geh unbeirrt meinen Weg. Ich kenne die Grundregeln von C/C++
Ich bin 2 Wochen lang jeden Tag mehrere Stunden drann gewesen und ich denke schon dass man sich da so einiges Aneignet.
Ich bleibe bei WIN32 API und ich hab jetzt auch ein bisschen Microsoft Literatur geschmöckert, aber das war ehrlich gesagt nicht sehr Hilfreich. Ich hab mir auch SFML angesehen, was ich Geil finde für Games, aber das möchte ich nicht.
Das was ich machen will, könnte ich wohl easy in VB coden, jedoch das ist mir wiederum zu "billig". Mich reizen komplizierte herausforderungen. Deshalb wird es bei C++ Win32 bleiben.Das Einzige was ich ändere ist meine IDE. Ich werde auf Visual Studio zurückgreifen. CodeBlocks ist geil aber irgendwie fehlt da was.
Ich hab unterdessen gelernt wie man Radiobuttons und Dropdown Selectoren benutzt und deren Variable übergibt