GUI in Dll

Infemo

Grünschnabel
Hallo Community,

ich bin neu hier im Forum. Da ich keine hilfreichen Informationen via Google erhalten habe, wende ich mich nun an euch und erhoffe mir hier einige ausfschlussreiche Antworten =)

Wie der Titel schon sagt möchte ich eine GUI in einer Dll verwenden, dieso verknüpfen oder sonst irgendwie miteinander Kommunizieren lassen, sodass ich Werte, die ich in meiner GUI einlese, in der Dll verarbeiten kann.

Ein einfaches Beispiel für die GUI:
Code:
#include <windows.h>
#include <stdio.h>
#include <cstdio>

HWND hwndButton;
HWND hwndEdit;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
{
	LPWSTR szName = L"Fensterklasse";
	WNDCLASS wc;

	wc.style			= CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc		= WndProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hInstance		= hI;
	wc.hIcon			= LoadIcon (NULL,IDI_WINLOGO);
	wc.hCursor			= LoadCursor (NULL, IDC_ARROW);
	wc.hbrBackground	= (HBRUSH) GetStockObject(GRAY_BRUSH);
	//wc.hbrBackground	= CreateSolidBrush(RGB(0,0,0));
	wc.lpszMenuName		= NULL;
	wc.lpszClassName	= szName;
	RegisterClass(&wc);

	HWND hwnd = CreateWindow(szName, L"<Graphical User Interface>", WS_SYSMENU | WS_SIZEBOX,
						     0,0,300,200,NULL,NULL,hI,NULL);

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);

	MSG msg;
	while(GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;

	switch(message)
	{
	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
			SetBkMode(hdc,TRANSPARENT);
			SetTextColor(hdc,RGB(0,0,0));

			TextOut(hdc, 20, 20, L"Wert", 4);
		EndPaint(hwnd, &ps);
		return 0;
	case WM_CREATE:
		hwndButton = CreateWindow(L"button", L"Einlesen!", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
								160, 20, 100, 18, hwnd, (HMENU)1, GetModuleHandle(0),0);

		hwndEdit = CreateWindow(L"edit",L"50", WS_VISIBLE | WS_CHILD, 
								60,20,80,17,hwnd,0, GetModuleHandle(0),0);
		break;
	case WM_COMMAND:
		switch(wParam)
		{
		case 1:
		{
			wchar_t text[256];

			SendMessage(hwndEdit, WM_GETTEXT, 256, (LPARAM)text);
			MessageBox(hwnd, text, L"Edit -- Feld", MB_OK);

			break;
		}
		}
		break;

	case WM_DESTROY:
		PostQuitMessage(0);

		return 0;
		
	}
	
	return DefWindowProc(hwnd, message, wParam, lParam);
}

Ein Beispiel für eine Dll:
Code:
#include <iostream>
#include <windows.h>
#include <detours.h>

DWORD WINAPI Thread(LPVOID unused) 
{
	//In diesem Thread hätte ich gerne (sofern dies so Verknüpfbar ist) eine Anweisung zB:
	//Die Ausgabe des Textes in dem Edit Feld der GUI
	//Nach drücken des "Einlesen Button" 
}


BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD Reason, LPVOID Reserved)
{
	switch(Reason)
	{
		case DLL_PROCESS_ATTACH:
			MessageBox(0,L"Attached.",L"Info",0);
			CreateThread(0, 0, Thread , 0, 0, 0);
			break;
		case DLL_PROCESS_DETACH:
			MessageBox(0,L"Detached.",L"Info",0);
			break;
	}
	return TRUE;
}


Ich würde mich sher über Antworten freuen!

Liebe Grüße
Infemo
 
Hi und Willkommen bei tutorials.de,

warum muss es unbedingt ein Thread sein?
Das verkompliziert das Ganze nur.

Prinzipiell musst du nur beim Buttondruck eben die DLL-Funktion aufrufen,
als wäre sie im Hauptprogramm.
Variablen, die zum Zugriff auf das Textfeld benötigt werden übergeben.
Fertig.
 
Danke für die schnelle Antwort. :)

Wie kann ich die DllMain denn innerhalb der GUI aufrufen? Es muss doch vorher überprüft werden ob die Dll attached ist oder nicht?
Oder verstehe ich dies falsch? :)
 
DllMain muss/soll man nicht selbst aufrufen
(und ich würde den Thread, wenn du ihn überhaupt brauchst, auch nicht dort starten).
DllMain wird von Windows automatisch aufgerufen, wenn die DLL geladen/entladen wird.

Den Thread starten (oder was sonst auch immer) sollte besser
in eine eigene Funktion ausgelagert werden.
Dazu schreibst du noch eine .h-Datei , die die Signaturen der Funktionen aus der DLL enthält.

zB. für den Thread:
C++:
DWORD WINAPI Thread(LPVOID unused);
Nur diesen Teil in die h-Datei.

Beim Kompilieren der DLL kommt dann auch eine .lib-Datei raus,
damit hast du alle drei (dll/lib/h).


Im Hauptprogramm schreibst du dann "#include<....h>" mit der .h-Datei dazu
und kompilierst die lib mit dem Hauptprogramm mit.
Dann wird die DLL beim Programmstart von selbst geladen.

Man könnte das Laden auch selbst programmieren...
Vorteil: Den Ladezeitpunkt kann man selbst bestimmen, und auch was passiert,
wenn die DLL nicht da ist (beim Autoload kann man ohne Dll
das ganze Programm nicht starten).
Nachteil: Komplizierter


Noch was: Je nach Compiler kann die .lib-Datei auch .a sein.

Noch was 2: __declspec nicht vergessen.

Gruß
 
Also erstmal, ist es relativ unrelevant (für mich) ob ich einen Thread nehme oder einfach irgend eine Funktion benutze. Ich möchte nur die Werte die ich in der GUI einlese in der .dll in einem/-r Thread/Funktion verwenden.

Die .dll Datei soll hinterher in einen fremden Prozess geladen werden, um dort Werte, welche vorher auf Knopfdruck in der GUI eingelesen wurden, zu verändern.
Ich habe das ganze an einen einfachen Spiel namens Inkball[sollte jedem bekannt sein] ausprobiert. Um die Dll einzuschleusen benutze ich Winject.
Wenn ich allerdings nun ein Hauptprogramm habe, was die Dll Datei lädt, dann kann ich die Dll Datei doch nichtmehr woanders injezieren oder?

Vielen Dank für Ihre Hilfe! =)
Liebe Grüße
Infemo
 
Zurück