GUI und/in Dll

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • GUI und/in Dll

    Hallo Community,

    nachdem mein Problem mit der GUI gelößt wurde, habe ich nun eine einwandfrei funktionierende, hübsche Oberfläche (siehe unten) :)
    Nun, diese Oberfläche würde ich gerne in eine Dll bringen, bzw. mit einer Dll kommunzieren lassen.
    Werte, welche ich auf Knopdruck in der GUI einlese, möchte ich in dieser Dll verarbeiten:

    C Source Code

    1. #include <iostream>
    2. #include <windows.h>
    3. #include <detours.h>
    4. BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD Reason, LPVOID Reserved)
    5. {
    6. switch(Reason)
    7. {
    8. case DLL_PROCESS_ATTACH:
    9. MessageBox(0,L"Attached.",L"Info",0);
    10. // SchreibeWert();
    11. // Funktion, welche einen eingelesenen Wert aus der GUI
    12. // verwendet.
    13. break;
    14. case DLL_PROCESS_DETACH:
    15. MessageBox(0,L"Detached.",L"Info",0);
    16. break;
    17. }
    18. return TRUE;
    19. }
    Display All


    Den grünen Bereich würde ich durch eine Funktion oder Quelltext ersetzen, welcher den eingelesenen Wert aus der GUI verwendet.
    Genauso sollte es auch andersrum funktionieren, werte die in der Dll benutzt werden, sollen in der GUI angezigt werden. :)

    Die Dll habe ich zu Testzwecken in den Prozess "Inkball" mit dem Programm "Winject" injeziert. Werte konnte ich aber hier nur durch die Benutzung von Hotkeys verändern.
    Dies möchte ich nun erleichtern indem ich eine Kontrolloberfläche, eine GUI, zur Bedienung hinzuziehe :)

    Meine einfache Oberfläche als Beispiel könnte so aussehen:

    C Source Code

    1. #include <windows.h>
    2. #include <stdio.h>
    3. #include <cstdio>
    4. #ifdef _UNICODE
    5. #if defined _M_IX86
    6. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
    7. #elif defined _M_X64
    8. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
    9. #else
    10. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    11. #endif
    12. #endif
    13. HWND hwndButton;
    14. HWND hwndEdit;
    15. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    16. int WINAPI WinMain(HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
    17. {
    18. LPWSTR szName = L"Fensterklasse";
    19. WNDCLASS wc;
    20. wc.style = CS_HREDRAW | CS_VREDRAW;
    21. wc.lpfnWndProc = WndProc;
    22. wc.cbClsExtra = 0;
    23. wc.cbWndExtra = 0;
    24. wc.hInstance = hI;
    25. wc.hIcon = LoadIcon (NULL,IDI_WINLOGO);
    26. wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    27. wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
    28. //wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
    29. wc.lpszMenuName = NULL;
    30. wc.lpszClassName = szName;
    31. RegisterClass(&wc);
    32. HWND hwnd = CreateWindow(szName, L"<Graphical User Interface>", WS_SYSMENU | WS_SIZEBOX,
    33. 0,0,300,200,NULL,NULL,hI,NULL);
    34. ShowWindow(hwnd, iCmdShow);
    35. UpdateWindow(hwnd);
    36. MSG msg;
    37. while(GetMessage(&msg,NULL,0,0))
    38. {
    39. TranslateMessage(&msg);
    40. DispatchMessage(&msg);
    41. }
    42. return msg.wParam;
    43. }
    44. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    45. {
    46. HDC hdc;
    47. PAINTSTRUCT ps;
    48. switch(message)
    49. {
    50. case WM_PAINT:
    51. hdc = BeginPaint(hwnd, &ps);
    52. SetBkMode(hdc,TRANSPARENT);
    53. SetTextColor(hdc,RGB(0,0,0));
    54. TextOut(hdc, 20, 20, L"Wert", 4);
    55. EndPaint(hwnd, &ps);
    56. return 0;
    57. case WM_CREATE:
    58. hwndButton = CreateWindow(L"button", L"Einlesen!", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
    59. 160, 20, 100, 18, hwnd, (HMENU)1, GetModuleHandle(0),0);
    60. hwndEdit = CreateWindow(L"edit",L"50", WS_VISIBLE | WS_CHILD,
    61. 60,20,80,17,hwnd,0, GetModuleHandle(0),0);
    62. break;
    63. case WM_COMMAND:
    64. switch(wParam)
    65. {
    66. case 1:
    67. {
    68. wchar_t text[256];
    69. SendMessage(hwndEdit, WM_GETTEXT, 256, (LPARAM)text);
    70. MessageBox(hwnd, text, L"Edit -- Feld", MB_OK);
    71. break;
    72. }
    73. }
    74. break;
    75. case WM_DESTROY:
    76. PostQuitMessage(0);
    77. return 0;
    78. }
    79. return DefWindowProc(hwnd, message, wParam, lParam);
    80. }
    Display All


    In dem rot gekennzeichneten Bereich lese ich einen Wert aus einem Edit Feld aus und speichere diesen in der Variable "text".
    Diesen würde ich nun in der Dll verwenden wollen.

    Allerdings bin ich ratlos, wie ich dies anstelle.
    Google hat zwar einige seiten ausgespuckt, jedoch war dies nicht allzu verständlich für mich! :(

    Über hilfreiche Antworten würde ich mich sehr freuen! :)
    Mit freundlichen Grüßen
    Infemo
  • Die Funktion DllMain wird beim laden und entladen der Bibliothek aufgerufen.

    Da du MSVS verwendest, erstell doch dein Bibliothek über den intigrierten Wizzard:
    Datei->Neu->Projekt ---> Visual C++ -> Win32 Projekt ---> DLL -> Fertig
    Dann kriegst du schon in etwa das was du gepostet als Vorlage.

    Nun kannst du hingeghen und eigen Funktionen definieren:

    Source Code

    1. int Add(int WertA, int WertB) { return WertA + WertB; }

    Um diese in deinem Hauptprogramm verwenden zu können muss diese als "Exportiert" markiert werden:

    Source Code

    1. __declspec(dllexport) int Add(int WertA, int WertB) { return WertA + WertB; }

    Wenn du nun die Bibliothek compilerst (Release) kriegst du zwei Dateien BibName.dll und BibName.lib.

    Diese zweite Datei BibName.lib musst du in deinem Hauptprojekt linken, unter MSVS am einfachsten mit:

    Source Code

    1. #pragma comment(lib, "Pfad/BibName.lib")

    Nun brauchst du nur noch den Prototyp der Funktion zu definieren und zu "importieren":

    Source Code

    1. __declspec(dllimport) int Add(int WertA, int WertB);

    Und schliesslich kannst du die Funktion benutzen:

    Source Code

    1. int Sum = Add(4,5);

    Anbei: Fortgeschritten arbeiten da, zur besseren Codeübersicht, jedoch in der Praxis mit Macros

    PS: Sorg Bitte dafür das dein anderer (gleicher) Thread doch entfernt/gelöscht wird.

    Mfg Rushh0ur

    The post was edited 1 time, last by Rushh0ur ().

  • Hallo Rushh0ur,

    vielen Dank für deine so umfang- und hilfreiche Antwort=)
    Entschuldige meine späte Antwort, jedoch war ich in den letzten Tage ziemlich eingesapnnt :/

    Also erstelle ich ein Projekt namen "Probe", so wie Sie es gesagt haben, bekomme ich zwei Header Dateien, zum einen eine stdafx.h und eine targetver.h.
    Die Quelldateien sind dllmain.cpp, Probe.cpp und stdafx.cpp.

    Compiliere ich dies ohne irgenetwas zu verändern bekomme ich eine Probe.dll, eine Probe.ilk und eine Probe.pdb.
    Mit letzteren weis ich nichts anzufangen.

    Allerdings fehlt hier weiterhin jede Spur einer GUI...muss ich dieses als neue Quelldatei hinzufügen?
    Da ich neu im Forum bin, weis ich leider nicht wie ich dies löschen kann, allerdings habe ich das Thema als "Erledigt" markiert =)

    Ich würde mich sehr über weitere Hilfestellungen freuen und bedanke mich nochmal bei Ihnen! :)

    Mit freundlichen Grüßen
    Infemo
  • Die lib wird nur erstellt wenn auch Funktionen exportiert werden.

    Ich hab dich etwas Falsch verstanden, das obige beschriebt wie du Funktionen einer DLL in deiner eigenen EXE verwenden kannst.

    Da du jedoch die DLL in einer anderen EXE, vom Code her dir unbekannt, ladest/injectes steht dir nur die DllMain funktion zur verfügung.
    Um nun dein Formular anzuzeigen musst du deinen Code in einem neuen Thread ausführen:

    Source Code

    1. #include "stdafx.h"
    2. #include "mylib.h"
    3. // Thread Handle (Identifikation)
    4. HANDLE hThread = NULL;
    5. // Eigene Threadroutin (Eigenes WinMain als Protyp in mylib.h definiert)
    6. DWORD APIENTRY MyThreadRoutine(LPVOID lpThreadParameter)
    7. {
    8. WinMain((HINSTANCE)lpThreadParameter, NULL, NULL, SW_SHOW);
    9. return 0;
    10. }
    11. // Dll Einstiegspunkt
    12. BOOL APIENTRY DllMain( HMODULE hModule,
    13. DWORD ul_reason_for_call,
    14. LPVOID lpReserved
    15. )
    16. {
    17. switch (ul_reason_for_call)
    18. {
    19. case DLL_PROCESS_ATTACH:
    20. // Thread erstellen
    21. DWORD idThread;
    22. hThread = CreateThread(NULL, NULL, &MyThreadRoutine, (LPVOID)hModule, 0, &idThread);
    23. break;
    24. case DLL_PROCESS_DETACH:
    25. // Eigenen Thread Terminieren, unschoen jedoch gits es keine andere Möglichkeit
    26. TerminateThread(hThread, -1);
    27. CloseHandle(hThread);
    28. break;
    29. }
    30. return TRUE;
    31. }
    Display All


    Mfg Rushh0ur
  • Die lib wird nur erstellt wenn auch Funktionen exportiert werden.
    Achso, okay.
    Ich hab dich etwas Falsch verstanden, das obige beschriebt wie du Funktionen einer DLL in deiner eigenen EXE verwenden kannst.
    Also zum teil möchte ich beides machen ;) 'Allerdings weniger Funktionen in meiner Exe Datei, sondern einfach nur Variablen in meiner Exe. Würde dies denn genaus so funktionieren, oder geht dies anders ?
    Da du jedoch die DLL in einer anderen EXE, vom Code her dir unbekannt, ladest/injectes steht dir nur die DllMain funktion zur verfügung.
    Um nun dein Formular anzuzeigen musst du deinen Code in einem neuen Thread ausführen

    Das heißt, dass ich in diesem Beispiel in die mylib.h die gesamte GUI packen müsste, damit ich ein Fenster habe, mit dem ich eingelesene Werte aus der GUI an die Dll übetragen kann?

    C Source Code

    1. #include <windows.h>
    2. #include <stdio.h>
    3. #include <cstdio>
    4. #ifdef _UNICODE
    5. #if defined _M_IX86
    6. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
    7. #elif defined _M_X64
    8. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
    9. #else
    10. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    11. #endif
    12. #endif
    13. HWND hwndButton;
    14. HWND hwndEdit;
    15. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    16. int WINAPI WinMain(HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
    17. {
    18. LPWSTR szName = L"Fensterklasse";
    19. WNDCLASS wc;
    20. wc.style = CS_HREDRAW | CS_VREDRAW;
    21. wc.lpfnWndProc = WndProc;
    22. wc.cbClsExtra = 0;
    23. wc.cbWndExtra = 0;
    24. wc.hInstance = hI;
    25. wc.hIcon = LoadIcon (NULL,IDI_WINLOGO);
    26. wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    27. wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
    28. //wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
    29. wc.lpszMenuName = NULL;
    30. wc.lpszClassName = szName;
    31. RegisterClass(&wc);
    32. HWND hwnd = CreateWindow(szName, L"<Graphical User Interface>", WS_SYSMENU | WS_SIZEBOX,
    33. 0,0,300,200,NULL,NULL,hI,NULL);
    34. ShowWindow(hwnd, iCmdShow);
    35. UpdateWindow(hwnd);
    36. MSG msg;
    37. while(GetMessage(&msg,NULL,0,0))
    38. {
    39. TranslateMessage(&msg);
    40. DispatchMessage(&msg);
    41. }
    42. return msg.wParam;
    43. }
    44. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    45. {
    46. HDC hdc;
    47. PAINTSTRUCT ps;
    48. switch(message)
    49. {
    50. case WM_PAINT:
    51. hdc = BeginPaint(hwnd, &ps);
    52. SetBkMode(hdc,TRANSPARENT);
    53. SetTextColor(hdc,RGB(0,0,0));
    54. TextOut(hdc, 20, 20, L"Wert", 4);
    55. EndPaint(hwnd, &ps);
    56. return 0;
    57. case WM_CREATE:
    58. hwndButton = CreateWindow(L"button", L"Einlesen!", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
    59. 160, 20, 100, 18, hwnd, (HMENU)1, GetModuleHandle(0),0);
    60. hwndEdit = CreateWindow(L"edit",L"50", WS_VISIBLE | WS_CHILD,
    61. 60,20,80,17,hwnd,0, GetModuleHandle(0),0);
    62. break;
    63. case WM_COMMAND:
    64. switch(wParam)
    65. {
    66. case 1:
    67. {
    68. wchar_t text[256];
    69. SendMessage(hwndEdit, WM_GETTEXT, 256, (LPARAM)text);
    70. MessageBox(hwnd, text, L"Edit -- Feld", MB_OK);
    71. break;
    72. }
    73. }
    74. break;
    75. case WM_DESTROY:
    76. PostQuitMessage(0);
    77. return 0;
    78. }
    79. return DefWindowProc(hwnd, message, wParam, lParam);
    80. }
    Display All


    Vielen Dank! Ich hoffe auf weitere Hilfeleistung :)

    Liebe Grüße
    Infemo

  • Das heißt, dass ich in diesem Beispiel in die mylib.h die gesamte GUI packen müsste, damit ich ein Fenster habe, mit dem ich eingelesene Werte aus der GUI an die Dll übetragen kann?

    Kurz gesagt ja (jedoch eher in die cpp-Datei), insofern sich das Formular nicht in der Zielanwendung anderweitig schon vorhanden ist, dann kann therotisch natürlich auch das Formular der Zielanwendung verwendet werden.

    Mfg Rushh0ur