WinAPI-Fenster aus Konsole heraus erstellen
-
Schönen Guten Abend,
der Titel sagt eigentlich schon alles aus. Ich möchte die ein oder andere alte Konsolenanwendung mit Win-Fenstern verbessern. Nach kurzer Suche habe ich auch dieses Beispiel gefunden. Nach kurzer Anpassung an meine Bedürfnisse kam auch ein funktionierendes Programm raus. Allerdings ist es nicht möglich z.B. einen Text im Win-Fenster auszugeben.Was mache ich falsch, wo liegt der Fehler?
Folgende Fehlermeldung: " main.o:main.cpp:(.text+0x2cf): undefined reference to `__imp_TextOutA' "
Schon einmal Vielen Dank für Antworten!
MFG John.PS: Wenn man die TextOut() entfernt funktioniert es...
#include <iostream> #include <fstream> #include <Windows.h> using namespace std; LRESULT CALLBACK WINDOW(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam); void WFenster(); int main(int argc, char* argv[]){ SetConsoleTitle("Konsole"); char go='b'; cout<<"Mit 'a' WFenster oeffnen!"<<endl<<endl<<"Ihre Eingabe: "; cin>>go; if(go=='a') WFenster(); return 0; } LRESULT CALLBACK WINDOW(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ switch(msg){ case WM_DESTROY:{ PostQuitMessage(0); }break; case WM_PAINT:{ PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 50, 50, "WFenster", sizeof("WFenster")); EndPaint(hWnd, &ps); }return 0; } return DefWindowProc(hWnd,msg,wParam,lParam); } void WFenster(){ WNDCLASSEX wcx; wcx.cbClsExtra=0; wcx.cbSize=sizeof(WNDCLASSEX); wcx.cbWndExtra=0; wcx.hbrBackground=(HBRUSH)COLOR_WINDOW; wcx.hCursor=LoadCursor(GetModuleHandle(NULL),IDC_ARROW); wcx.hIcon=LoadIcon(GetModuleHandle(NULL),NULL); wcx.hIconSm=wcx.hIcon; wcx.hInstance=GetModuleHandle(NULL); wcx.lpfnWndProc=WINDOW; wcx.lpszClassName="WFenster"; wcx.lpszMenuName=NULL; wcx.style=CS_HREDRAW|CS_VREDRAW; if(!RegisterClassEx(&wcx)){ cout<<endl<<"-----Registrierung der Fensterklasse fehlgeschlagen!\n-----"; cin.get(); exit(-1); } HWND hWnd=CreateWindowEx(0,"WFenster","WFenster",WS_OVERLAPPEDWINDOW,50,50,500,500,0,0,GetModuleHandle(NULL),0); if(!hWnd){ cout<<endl<<"-----Fenster konnte nicht erzeugt werden!\n-----"; cin.get(); exit(-2); } ShowWindow(hWnd, SW_NORMAL); UpdateWindow(hWnd); MSG msg; while(GetMessage(&msg,0,0,0)){ TranslateMessage(&msg); DispatchMessage(&msg); } }
-
Lies dir mal die Requirements durch: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145133(v=vs.85).aspx (ganz unten).
Und dann überlegst du, was ein Linkererror bedeutet und wie man ihn eventuelle lösen könnte.
-
Hallo,
nach langer Suche mit deinem Hinweis habe ich tatsächlich dann die Lösung gefunden: unter Optionen bei Linker "-lgdi32" hinzugefügt. - Vielen Dank.Es bleibt nur für mich die Frage offen, in wie weit derartige Probleme mit anderen Funktionen ebenfalls noch auftreten können/werden?
Soweit ich das verstanden habe, wird die Bibliothek in der TextOut() definiert ist nicht gefunden/benutzt weil es eine Konsolen-Anwendung ist. Kann man dem Compiler direkt im Code sagen, dass er diese einbinden soll/muss, weil jedes mal über die Optionen ist ziemlich umständlich...Schönen Abend!
John.
-
Das wird dir vermutlich noch öfters passieren, da Windows viele viele verschiedene DLLs mitbringt.
Die drei wichtigsten sind KERNEL32, USER32 und GDI32.Guck in den Link von Nathan. Da steht:
MSDN schrieb:
Library Gdi32.lib
Das heisst du musst die "Gdi32.lib" einbinden.
Genau das machst du jetzt mit-lgdi32
Das "-l" ist dabei der Switch, und "gdi32" der Name der Library.
Wenn du also gegen eine Library "Trullala.lib" linken willst, dann musst du halt den Switch-lTrullala
anhängen.Und der Funktionsname, über den du die passende MSDN Seite findest, steht ja in der Fehlermeldung:
__imp_TextOutA
Der "__imp_" Prefix bedeutet lediglich dass es sich um eine DLL Funktion handelt.Und das "A" hinten ist eine Windows-Eigenart. Es gibt nämlich viele Funktionen zwei mal, 1x als "ANSI" Version und 1x als "UNICODE" Version. Die ANSI Versionen haben hinten ein grosses "A" angehängt, und die "UNICODE" Versionen ein grosses "W".
Das ganze bis ins Detail zu erklären würde nu etwas zu lange dauern. Warum ich das trotzdem erwähne: nachdem du das "__imp_" entfernt hast bleibt noch ein Teil übrig (in diesem Fall "TextOutA"). Und wenn der in einem grossen A oder W endet, nimmst du das auch noch weg. Und dann googelst du einfach den Funktionsnamen, oder ggf. "Funktionsname MSDN" (ohne "").=> MSDN Seite
=> Library Name
=> Linker-Switch eintragen
=> Problem gelöstOder du verwendest einfach Visual C++. Da ist das alles sehr viel einfacher, da die meisten Libraries über
#pragma comment
automatisch eingebunden werden.
-
Hallo,
Vielen Dank für deine Erklärung!
Für die Zukunft werde ich damit keine Probleme mehr haben...
MFG John.