C++ Winapi Variable in Funktionsaufruf

üäpöol

Erfahrenes Mitglied
Liebe Forummitglieder,

ich gerade mit Winapi angefangen und schreibe gerade an einem Programm, mit dem man eine Linie zeichnen kann.
Man klickt auf einen Punkt mit der linken Maustaste und dann auf einen Punkt mit der rechten Maustaste. Diese habe ich jetzt mit Variablen definiert.

Wie kann ich jetzt aber diese Variable in die Funktionen LineTo() und MoveToEx() "tun" ?
Ich hab schon ewig gesucht, finde aber nicht hilfreiches dazu.

Lg

üäpöol
 
Hi

was meinst du damit, dass du die Maustasten mit Variablen definiert hast?
Kannst du den Code zeigen? Damit könnte man dir besser helfen...

Gruß
 
Hi,

erstmal vielen Dank für die An twort.
Hier der Code:

Code:
// Linie zeichnen.cpp : Definiert den Einstiegspunkt für die Anwendung.
//

#include "stdafx.h"
#include "Linie zeichnen.h"

bool Zeichnen = false;

#define MAX_LOADSTRING 100


// Globale Variablen:
HINSTANCE hInst;								// Aktuelle Instanz
TCHAR szTitle[MAX_LOADSTRING];					// Titelleistentext
TCHAR szWindowClass[MAX_LOADSTRING];			// Klassenname des Hauptfensters

// Vorwärtsdeklarationen der in diesem Codemodul enthaltenen Funktionen:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Hier Code einfügen.
	MSG msg;
	HACCEL hAccelTable;

	// Globale Zeichenfolgen initialisieren
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_LINIEZEICHNEN, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Anwendungsinitialisierung ausführen:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_LINIEZEICHNEN));

	// Hauptnachrichtenschleife:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  FUNKTION: MyRegisterClass()
//
//  ZWECK: Registriert die Fensterklasse.
//
//  KOMMENTARE:
//
//    Sie müssen die Funktion verwenden,  wenn Sie möchten, dass der Code
//    mit Win32-Systemen kompatibel ist, bevor die RegisterClassEx-Funktion
//    zu Windows 95 hinzugefügt wurde. Der Aufruf der Funktion ist wichtig,
//    damit die kleinen Symbole, die mit der Anwendung verknüpft sind,
//    richtig formatiert werden.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LINIEZEICHNEN));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_LINIEZEICHNEN);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNKTION: InitInstance(HINSTANCE, int)
//
//   ZWECK: Speichert das Instanzenhandle und erstellt das Hauptfenster.
//
//   KOMMENTARE:
//
//        In dieser Funktion wird das Instanzenhandle in einer globalen Variablen gespeichert, und das
//        Hauptprogrammfenster wird erstellt und angezeigt.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNKTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  ZWECK:  Verarbeitet Meldungen vom Hauptfenster.
//
//  WM_COMMAND	- Verarbeiten des Anwendungsmenüs
//  WM_PAINT	- Zeichnen des Hauptfensters
//  WM_DESTROY	- Beenden-Meldung anzeigen und zurückgeben
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
    case WM_LBUTTONDOWN:
		if (Zeichnen)
	{
    {
    int iPosX = LOWORD(lParam);
    int iPosY = HIWORD(lParam);
    wchar_t waCoord[20];
	}
    break;
    }
   case WM_RBUTTONDOWN:
		if (Zeichnen)
	{
    {
    int jPosX = LOWORD(lParam);
    int jPosY = HIWORD(lParam);
    wchar_t waCoord[20];
	}
    break;
    }
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Menüauswahl bearbeiten:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Hier den Zeichnungscode hinzufügen.
		HPEN hPenOld;

		{

		int Linie = MessageBox(hWnd, _T("Möchtest du eine Linie ziehen?"), _T("Zeichnen?"), MB_YESNO);

		switch (Linie)
		{
		case IDYES: 
			MessageBox(hWnd, _T("Du kannst jetzt eine Linie ziehen, indem du mit der linken Maustaste auf den Startpunkt und mit der rechten Maustaste auf den Endpunkt klickst!"), _T("Linie zeichnen"), MB_OK);
			HPEN hLinePen;
			COLORREF qLineColor;
			qLineColor = RGB(255, 0, 0);
			hLinePen = CreatePen(PS_SOLID, 7, qLineColor);
			hPenOld = (HPEN)SelectObject(hdc, hLinePen);

			MoveToEx(hdc, /* hier soll die Variable iPosX rein */  100 , /* hier soll die Variable iPosY rein */  100, NULL);
			LineTo(hdc, /* hier soll die Variable jPosX rein */ 500, /* hier soll die Variable jPosY rein */ 250);

			SelectObject(hdc, hPenOld);
			DeleteObject(hLinePen);

			break;
		case IDNO:  
			MessageBox(hWnd, _T("Und wofür hast du dann das Programm geöffnet?"), _T("****?"), MB_OK);
			break;

		}

		}

	

		

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Meldungshandler für Infofeld.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

Der müsste eigentlich so funktionieren.

Lg

üäpöol
 
Wenn du die Variable erst im L/R-BUTTONDOWN anlegst, kannst du außerhalb davon (außerhalb der {} ) nicht darauf zugreifen.

Mach die zwei ints außerhalb von L/R-BUTTONDOWN, gerade noch innerhalb von WndProc.
Dann kannst du auch in der restlichen Funktion darauf zugreifen.

Gruß
 
Äh, in WndProc hilft aber auch nicht, die wird für jede Windows-Nachricht neu durchlaufen. Damit sind die alten Werte futsch.
Du kannst die als

static int

innerhalb der WndProc anlegen, dann bleiben die Werte auch stehen.
 
Stimmt...
(man könnte aber auch ein goto zu WM_PAINT machen und sich darauf verlassen, dass das Zeichnen Funktioniert :D)

Danke für die Korrektur.
 
Hm ...
Also wie gesagt, ich bin Anfänger und verstehe leider gerade nicht ganz bzw. überhaupt nicht worüber euch unterhaltet.
Wäre super, wenn ihr mir das ganze so erklären könnten, dass ich es verstehe. :D
 
C++:
int x = 2;
/// x ist hier sichtbar
{
   int y = 4;
   x = y;
   /// x und y sind hier sichtbar
}
/// y ist hier nicht mehr sichtbar, x schon

Deine Variabeln müssten also an einem Ort deklariert werden an dem sie sowohl für WM_PAINT als auch für WM_RBUTTONDOWN ersichtlich sind. Das Problem ist aber, dass diese Variabeln dann in jedem Funktionsaufruf neu angelegt würden und somit ihre alten Werte nicht mehr hätten. Um das zu "umgehen" kannst du sie zum Beispiel statisch deklarieren.
 
Ah. Vielen Dank! :)
Aber wie was bedeutet "eine Variable statisch deklarieren"?
Ich hoffe ich geh euch nicht mit meinen Anfängerproblemen auf ide Nerven! :D
 
Das bedeutet, dass es von dieser Variabeln nur ein Exemplar gibt. Gleichzeitig wird aber durch den Ort der Deklaration bestimmt wo sie sichtbar ist. Das funktioniert folgendermassen:
C++:
void foo()
{
   /// Davon existiert nur eine globale Version
   static float sFloat;
   /// Davon wird in jedem Funktionsaufruf eine neue Version erstellt.
   float vFloat;
}
 
Zurück