HDC global... GetDC überschreibt alles?



  • Der Code hat sich verändert:

    PAINTSTRUCT myPaint;
    static POINT myPoint,
    				 mousePointForPaint;
    static RECT myRect;
    
    static BOOL isPainting;
    
    static COORD mouseKoord;
    
    HANDLE backUp;
    
    if( LOWORD(lParam) != 0 || HIWORD(lParam) != 0)
    {
    	mouseKoord.X = LOWORD(lParam);	//took the mouse-coordinates into a COORD variable (perfomance)
    	mouseKoord.Y = HIWORD(lParam);
    }
    [...]
    			case WM_PAINT:
    			//zum Zeichnen anmelden
    			myHdc = BeginPaint( myWnd, &myPaint );
    			{
    				if( myPoint.x != -1 )
    				{
    					backUp = SelectObject( myHdc, *aktPen );
    					MoveToEx(
    							myHdc,				//Zeichenfläche
    							myPoint.x,			//X-Koordinate
    							myPoint.y,			//Y-Koordinate
    							NULL				//old-Koordinate
    					);
    					LineTo(
    						myHdc,					//Zeichenfläche
    						mousePointForPaint.x,	//X-Koordinate
    						mousePointForPaint.y	//Y-Koordinate
    					);
    
    					SelectObject( myHdc, backUp );
    				}
    			}
    			EndPaint( myWnd, &myPaint );
    			visitMsg = TRUE;
    		break;
    		case WM_MOUSEMOVE:
    			myHdc = GetDC( myWnd );			//open device-context (paintplace)
    			{
    				if( !isPainting )			//Wenn der 
    				{
    					if( inRect( mouseKoord, blackColor ) )
    					{
    						aktPen = &blackPen;								//slect black pen
    
    						R = 0;
    						G = 0;
    						B = 0;
    					}
    					else if( inRect( mouseKoord, whiteColor ) )
    					{
    						aktPen = &whitePen;								//select white pen
    
    						R = 255;
    						G = 255;
    						B = 255;
    					}
    					else if( inRect( mouseKoord, smallSize ) )
    					{
    						DeleteObject( aktPen );
    						*aktPen = CreatePen( PS_SOLID, 1, RGB( R, G, B ) );
    					}
    					else if( inRect( mouseKoord, middleSize ) )
    					{
    						DeleteObject( aktPen );
    						*aktPen = CreatePen( PS_SOLID, 3, RGB( R, G, B ) );
    					}
    					else if( inRect( mouseKoord, bigSize ) )
    					{
    						DeleteObject( aktPen );
    						*aktPen = CreatePen( PS_SOLID, 4, RGB( R, G, B ) );
    					}
    				}
    				else
    				{
    					if( myPoint.x != -1 )
    					{
    						mousePointForPaint.x = mouseKoord.X;
    						mousePointForPaint.y = mouseKoord.Y;
    						InvalidateRect( myWnd, NULL, TRUE);	//send WM_PAINT so that the painting is just standing, if the window will be resized
    						myPoint.x = mouseKoord.X;					//set new coordinates
    						myPoint.y = mouseKoord.Y;
    					}
    					else
    					{
    						myPoint.x = mouseKoord.X;//The first coordinates
    						myPoint.y = mouseKoord.Y;
    					}
    				}
    				visitMsg = TRUE;
    			}
    			ReleaseDC( myWnd, myHdc );
    		break;
    


  • Wo wird isPainting gesetzt? 😕
    Die DeleteObject-Blöcke finden nur bei !isPainting statt. Da isPainting nirgends gesetzt wird, ist es vorläufig offenbar immer 0.



  • case WM_LBUTTONDOWN:
    			isPainting = TRUE;
    			visitMsg = TRUE;
    		break;
    		case WM_LBUTTONUP:
    			isPainting = FALSE;
    
    			myPoint.x = -1;
    			myPoint.y = -1;
    
    			visitMsg = TRUE;
    		break;
    

    😃



  • Mein Gott, machst du es kompliziert!

    Wenn WM_LBUTTONDOWN kommt, wird isPainting auf TRUE gesetzt- aber gleich danach, beim Loslassen (WM_LBUTTONUP) wieder auf FALSE. Was soll das denn?
    isPainting ist damit völlig überflüssig.

    Wenn Du während der Mausbewegung zeichnen willst, kannst Du wParam von WM_MOUSEMOVE abfragen:

    WM_MOUSEMOVE  
    fwKeys = wParam;        // key flags 
    xPos = LOWORD(lParam);  // horizontal position of cursor 
    yPos = HIWORD(lParam);  // vertical position of cursor 
    
    Parameters
    
    fwKeys
    Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values: 
    
    Value	Description
    MK_CONTROL	Set if the CTRL key is down.
    MK_LBUTTON	Set if the left mouse button is down.
    MK_MBUTTON	Set if the middle mouse button is down.
    MK_RBUTTON	Set if the right mouse button is down.
    MK_SHIFT	Set if the SHIFT key is down.
    


  • Du redest so als müsste ich ein API-King sein, und dann hättest du auch das recht so über meinen Code zu reden...

    Ich wusste nicht das bei WM_MOUSEMOVE wParam einer aus der netten liste sein kann..

    Habe es umgeschrieben... gleiche symtome wie vorher, dass heißt es klappt...

    Also ich kann immer noch nicht zeichnen !? aber dass mit dem wParam klappt... 7 Zeilen code eingespart 😃

    LRESULT CALLBACK StaticProc[...]
    

    scheint ja wohl messages von

    [...]= CreateWindow( "STATIC", *INHALT*, WS_CHILD | WS_VISIBLE | WS_DLGFRAME , *POSX*, *POSY*, *WIDTH*, *HEIGHT*, *PARENT*, NULL, *INSTANCE*, NULL );
    

    zu bekomme richtig!?

    Bei mir nicht... http://msdn2.microsoft.com/en-us/library/bb760769(VS.85).aspx->using static controls sagt das soll so gehen...

    [edit]Danke trotzdem für deinen Post, vereinfacht den Code 🕶



  • lippoliv schrieb:

    Du redest so als müsste ich ein API-King sein, und dann hättest du auch das recht so über meinen Code zu reden...

    Nichts für ungut. Ich bin auch kein Experte. Aber in Deinem Code treten nach und nach immer neue Fehler zu tage, weil Du 1. nicht den vollständigen Code postest, und 2. gar nicht weißt, welche Codeteile Du posten mußt, um den Fehler einzugrenzen. Das wiederum zeigt, daß Du von der WinAPI noch weniger verstanden hast als ich.

    Deshalb habe ich Dir die Tutorials ans Herz gelegt, bevor Du Dich an solche Projekte wagst. Sind nicht der Weisheit letzter Schluß, aber man kann daraus einiges lernen, z. B. den Umgang mit den Maustasten oder die Zuordnung der richtigen Funktionen und Variablen an die WM-Nachrichten. Wichtig ist, daß Du Dich mit den darin behandelten WM-Nachrichten und Funktionen auseinandersetzt. Und wenn Du die Programme ein wenig variierst, kann das sehr interessant werden.

    Ein Static Control hat nichts mit der Maus und nichts mit dem Schlüsselwort STATIC zu tun, sondern ist eine spezielle Art von Ausgabefenster.

    LRESULT CALLBACK StaticProc[...]
    

    scheint ja wohl messages von

    [...]= CreateWindow( "STATIC", *INHALT*, WS_CHILD | WS_VISIBLE | WS_DLGFRAME , *POSX*, *POSY*, *WIDTH*, *HEIGHT*, *PARENT*, NULL, *INSTANCE*, NULL );
    

    zu bekomme richtig!?

    Falsch. CreateWindow liefert nur das hWnd zurück. Die Messages werden von der Nachrichtenschleife (TranslateMessage, DispatchMessage) in der WinMain an das jeweilige Fenster geleitet. Jede Message enthält das Handle des Zielfensters.



  • Ich lasse deinen Beitrag mal unkommentiert stehen da ich gerade nicht weiß ob ich mich total irre, oder du nicht ganz verstehst nach welcher art ich meine Codes poste, denn ich will euch nicht mit unsinnigem Code überfluten. Ich mache mir stets gedanken, welche codes ihr braucht und Poste diese dann, ich hatte halt eben nur diesen teil mit dem setzen der Maus vergessen.

    Ist in den Tutorials wirklich dass mit WM_LBUTTON drinne? *nochmal nachschau*

    Elektronix schrieb:

    Falsch. CreateWindow liefert nur das hWnd zurück. Die Messages werden von der Nachrichtenschleife (TranslateMessage, DispatchMessage) in der WinMain an das jeweilige Fenster geleitet. Jede Message enthält das Handle des Zielfensters.

    So wie ich dass von MSDN verstanden habe ist dass Falsch.
    Die Messages gehen nicht an das Handle, sondern an die klasse die mit dem Handle zusammen hängt.

    Bei STATIC soll das dieses sein was ich gepostet habe denn:
    http://msdn2.microsoft.com/en-us/library/ms632679.aspx => weiter unten LINK "Static Controls"
    http://msdn2.microsoft.com/en-us/library/bb760769(VS.85).aspx => uiui...

    😮 Notifications sind keine Messages ne!? Wie erhalte ich denn "STN_CLICKED" was dort unter Notification steht...
    Ich kann doch nicht einfach:

    LRESULT CALLBACK WndProc( HWND myWnd, UINT givenMessage, WPARAM wParam, LPARAM lParam )
    /*
    	This function recieves the Messages, wich are given from MS-Windows to the program.
    	So the program can do message specific actions, if this message is incoming.
    */
    {
    	switch( givenMessage )
    	{
    [...]
    		case WM_COMMAND:
    			if( myWnd == whiteBtn )
    				printf( "." );
    		break;
    [...]
    

    schreiben, da zeigt er auch keinen "." an.
    whiteBtn = ein STATIC wnd.
    auchg wenn ich

    LRESULT CALLBACK WndProc( HWND myWnd, UINT givenMessage, WPARAM wParam, LPARAM lParam )
    /*
    	This function recieves the Messages, wich are given from MS-Windows to the program.
    	So the program can do message specific actions, if this message is incoming.
    */
    {
    	switch( givenMessage )
    	{
    [...]
    		case WM_COMMAND:
    			printf( "." );
    		break;
    [...]
    

    schreibe passiert nichts.

    LÖSUNG:
    ^(nach genauem lesen, und weiterem überlegen fügte ich bei windowCreate nochmal SS_NOTIFY hinzu)^

    case WM_COMMAND:
    			if( myWnd = whiteBtn)
    				printf( "." );
    		break;
    

    Jetzt verbleibt aber noch das problem mit dem malen, WOBEI ich herausgefunden habe, dass ich einen punkt hinbekomme... Wenn ich eine Farbe wähle, wird ein punkt gezogen und bei dem px wo WM_LBUTTONUP kommt, bleibt dieser PX (je nach width auch mehrere) in der gewählten farbe.



  • VERDAMMT.... 😡 😡 😃

    if( myWnd = whiteBtn)
    

    kein wunder dass das klappt...

    irgendwie haut das mit == nicht mehr hin... dabei sollte dass doch gehen?!?

    [edit]

    Elektronix schrieb:

    Die Messages werden von der Nachrichtenschleife (TranslateMessage, DispatchMessage) in der WinMain an das jeweilige Fenster geleitet. Jede Message enthält das Handle des Zielfensters.

    Kann es sein dass du "Parentfenster" meinst?

    case WM_COMMAND:
    			if( myWnd == myAppWnd )
    			{
    				printf( "." );
    
    				aktPen = &whitePen;								//select white pen
    
    				R = 255;
    				G = 255;
    				B = 255;
    			}
    			else 
    			{
    				printf( "%d != %d\n", myWnd, whiteBtn );
    			}
    		break;
    

    myAppWnd == handle meines Hauptfensters...
    Ich dachte es müste (zielgerichtet) an das Static genster gehen, was ich geklickt habe... 😞

    Also:
    Ich habe STATIC fenster eingebaut, weil Buttons zu dick waren.
    Wenn ein STATIC fenster geklickt wird, wird an das ParentWnd ein WM_COMMAND gesendet.

    NUR: wie kann ich jetzt rausbekommen welches STATIC geklickt wurde?
    Anhand der Mauskoordinaten? währ ja umständlich, dann müsste ich ja immer wissen, wo gerade meine STATICs sind.

    MFG und danke für jeden post (auch wenns manchmal nicht so aussieht danke ich euch wirklich)

    [edit2]

    case WM_COMMAND:
    			if( STN_CLICKED == wParam )
    			{
    				if( whiteBtn == ? )
    					printf( "." );
    			}
    			else 
    			{
    				printf( "%d != %d\n", myWnd, whiteBtn );
    			}
    		break;
    

    whiteBtn global HWND
    ich bekomme jetzt schonmal mit dass ein STATIC geklickt wird.
    http://msdn2.microsoft.com/en-us/library/bb760784(VS.85).aspx
    lParam: Handle to the static control.

    STN_CLICKED.lParam //gibt es nicht
    
    whiteBtn == HI/LOWORD(lParam); //geht nicht comparission between pointer and integer
    

    wie kann ich jetzt also lParam(was ja anscheinend das handle des geklickten STATIC enthält) mit meinen STATICs vergelichen?



  • lippoliv schrieb:

    Ist in den Tutorials wirklich dass mit WM_LBUTTON drinne? *nochmal nachschau*

    Mit Sicherheit ja!

    Elektronix schrieb:

    Falsch. CreateWindow liefert nur das hWnd zurück. Die Messages werden von der Nachrichtenschleife (TranslateMessage, DispatchMessage) in der WinMain an das jeweilige Fenster geleitet. Jede Message enthält das Handle des Zielfensters.

    So wie ich dass von MSDN verstanden habe ist dass Falsch.
    Die Messages gehen nicht an das Handle, sondern an die klasse die mit dem Handle zusammen hängt.

    Falsch. Eine Klasse ist nur ein Gerüst, von der erstmal per CreateWindow eine Instanz erstellt werden muß.
    Du kannst mehrere Fenster der gleichen Klasse erstellen. Wie soll dann das Programm wissen, für welches Fenster die Nachricht bestimmt ist? Das wird über das Handle gefunden, welches dem Fenster- ⚠ nicht der Klasse ⚠ - per CreateWindow zugeordnet ist.

    Bei STATIC soll das dieses sein was ich gepostet habe denn:
    http://msdn2.microsoft.com/en-us/library/ms632679.aspx => weiter unten LINK "Static Controls"
    http://msdn2.microsoft.com/en-us/library/bb760769(VS.85).aspx => uiui...

    MSDN schrieb:

    STATIC

    Designates a simple text field, box, or rectangle used to label, box, or separate other controls. Static controls take no input and provide no output. For more information, see Static Controls.

    For a table of the static control styles you can specify in the dwStyle parameter, see Static Control Styles.



  • Siehe mein edit

    Elektronix schrieb:

    MSDN schrieb:

    For more information, see Static Controls.

    ^^ das habe ich getan



  • lippoliv schrieb:

    Elektronix schrieb:

    Die Messages werden von der Nachrichtenschleife (TranslateMessage, DispatchMessage) in der WinMain an das jeweilige Fenster geleitet. Jede Message enthält das Handle des Zielfensters.

    Kann es sein dass du "Parentfenster" meinst?

    case WM_COMMAND:
    			if( myWnd == myAppWnd )
    			{
    				printf( "." );
    				
    				aktPen = &whitePen;								//select white pen
    				
    				R = 255;
    				G = 255;
    				B = 255;
    			}
    			else 
    			{
    				printf( "%d != %d\n", myWnd, whiteBtn );
    			}
    		break;
    

    myAppWnd == handle meines Hauptfensters...
    Ich dachte es müste (zielgerichtet) an das Static genster gehen, was ich geklickt habe... 😞

    Sorry- aber das wird ja immer !=besser...

    Schau Dir mal die WndClass-Struktur an. Da gibt es einen Member namens lpfnWndProc. Jede Fensterklasse (auch die vordefinierten!) hat eine WndProc. Bei selbst erstellten Klassen mußt Du die eben auch selbst implementieren. In der Parameterliste stehen das hWnd, die Message und die params.
    Also: Die Nachricht wird an ein Fenster gesendet, daß das entsprechende Handle hat. Sie wird dann von der WndProc des Fensters ausgewertet. Die WinMain hat gar kein Fenster, sondern ERSTELLT sie nur und leitet die Nachrichten dahin weiter. (in Ausnahmefällen kann man Nachrichten auch in der WinMain bearbeiten, führt aber zu weit).

    Ich habe STATIC fenster eingebaut, weil Buttons zu dick waren.
    Wenn ein STATIC fenster geklickt wird, wird an das ParentWnd ein WM_COMMAND gesendet.

    NUR: wie kann ich jetzt rausbekommen welches STATIC geklickt wurde?
    Anhand der Mauskoordinaten? währ ja umständlich, dann müsste ich ja immer wissen, wo gerade meine STATICs sind.

    MFG und danke für jeden post (auch wenns manchmal nicht so aussieht danke ich euch wirklich)

    Du kannst ein Static nicht als Button mißbrauchen. Ein Static nimmt keine Klicks an und sendet auch keine Nachrichten, es dient ausschließlich zur Anzeige. Daher kannst Du auch nicht herausfinden, welches Static gedrückt wurde.
    Über Static Controls muß ich nochmal genauer nachlesen.

    Die Größe der Buttons läßt sich in CreateWindow() festlegen (anstatt CW_USEDEFAULT). Sollte natürlich die Beschriftung reinpassen.



  • Ok dass man bei CreateWindow die breite bestimmen kann weis ich, waren aber aufgrund des Rahmen immer noch zu dick.

    Anhand der Notifications auf dieser seite http://msdn2.microsoft.com/en-us/library/bb760769(VS.85).aspx dachte ich halt ich könnte die zurechtbiegen.

    Elektronix schrieb:

    [...]Also: Die Nachricht wird an ein Fenster gesendet, daß das entsprechende Handle hat. Sie wird dann von der WndProc des Fensters ausgewertet. Die WinMain hat gar kein Fenster, sondern ERSTELLT sie nur und leitet die Nachrichten dahin weiter. [...]

    Die WinMain hat kein Fenster, das weiss ich.

    Elektronix schrieb:

    Sorry- aber das wird ja immer !=besser...

    Wenn dass schlechter hießen soll, kannst du da bitte genauer werden, damit ich eine chance habe ein !(!=besser) draus zu machen 🤡 😉

    Ich mach erstmal feierabend, morgen werde ich dann alles zu Buttons mahen, und mal schauen dass ich das Hinbekomme.

    Könnte irgendjemand nochmal den Fehler bei meinem Zeichnen mit MOUSEMOVE sagen, da ich ehrlich nicht weiß was da fehlt, ich poste mal nur die globalen variablen und mein WndProc, ich schätze das dürfte reichen.

    //Globale Variablen
    HINSTANCE myHandleInst;
    HWND myConsole,
    	 myAppWnd,
    	 closeBtn,
    	 blackBtn,
    	 whiteBtn,
    	 versionWnd,
    	 smallBtn,
    	 middleBtn,
    	 bigBtn;
    RECT closeButton,    //kommen noch alle weg, wegen der buttons
    	 blackColor,
    	 whiteColor,
    	 smallSize,
    	 middleSize,
    	 bigSize;
    HPEN whitePen,
    	 blackPen;
    HPEN *aktPen;
    HDC myHdc;    //muss glauube ich nicht mehr global sein, werde morgen nachschauen
    int R,
    	G,
    	B;
    BOOL realClose;
    [...]
    LRESULT CALLBACK WndProc( HWND myWnd, UINT givenMessage, WPARAM wParam, LPARAM lParam )
    /*
    	This function recieves the Messages, wich are given from MS-Windows to the program.
    	So the program can do message specific actions, if this message is incoming.
    */
    {
    	PAINTSTRUCT myPaint;
    	//Handle für Gerätekontext(gültiger Zeichenbereich)
    	BOOL visitMsg = FALSE;
    
    	static POINT myPoint,
    				 mousePointForPaint;
    
    	static RECT myRect,
    				parent;
    
    	static COORD mouseKoord;
    
    	HANDLE backUp;
    
    	char version[50];
    
    	if( LOWORD(lParam) != 0 || HIWORD(lParam) != 0)
    	{
    		mouseKoord.X = LOWORD(lParam);	//took the mouse-coordinates into a COORD variable (perfomance)
    		mouseKoord.Y = HIWORD(lParam);
    	}
    
    	switch( givenMessage )
    	{
    		case WM_CREATE:
    			myPoint.x = -1;
    			myPoint.y = -1;
    
    			GetClientRect( myAppWnd, &parent );
    
    			closeBtn = CreateWindow( "STATIC", "Closed", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top, 50, 20, myWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			blackBtn = CreateWindow( "STATIC", "black", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+30, 40, 20, myWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			whiteBtn = CreateWindow( "STATIC", "white", SS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+50, 40, 20, myWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    
    			strcpy( version, "Version: " );
    			strcat( version, VERSION );
    
    			versionWnd = CreateWindow( "STATIC", version, WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left+630, parent.bottom+555, 165, 20, myWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			smallBtn = CreateWindow( "STATIC", " 1px", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+75, 40, 22, myWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			middleBtn = CreateWindow( "STATIC", " 3px", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+97, 40, 22, myWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			bigBtn = CreateWindow( "STATIC", " 5px", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+119, 40, 22, myWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    
    			visitMsg = TRUE;
    		break;
    		case WM_SIZE:
    			myRect.left = 0;
    			myRect.top = 0;
    			myRect.bottom = HIWORD( lParam );
    			myRect.right = LOWORD( lParam );
    
    			visitMsg = TRUE;
    		break;
    		case WM_PAINT:
    			//zum Zeichnen anmelden
    			myHdc = BeginPaint( myWnd, &myPaint );
    			{
    				if( myPoint.x != -1 )
    				{
    					backUp = SelectObject( myHdc, *aktPen );
    					MoveToEx(
    							myHdc,				//Zeichenfläche
    							myPoint.x,			//X-Koordinate
    							myPoint.y,			//Y-Koordinate
    							NULL				//old-Koordinate
    					);
    					LineTo(
    						myHdc,					//Zeichenfläche
    						mousePointForPaint.x,	//X-Koordinate
    						mousePointForPaint.y	//Y-Koordinate
    					);
    
    					SelectObject( myHdc, backUp );
    				}
    			}
    			EndPaint( myWnd, &myPaint );
    			visitMsg = TRUE;
    		break;
    		case WM_MOUSEMOVE:
    			myHdc = GetDC( myWnd );			//open device-context (paintplace)
    			{
    				if( wParam != MK_LBUTTON )			//Wenn der 
    				{
    					if( inRect( mouseKoord, blackColor ) )//dass kommt fast alles raus (die ifs und elss ifs) wegen den buttons
    					{
    						aktPen = &blackPen;								//slect black pen
    
    						R = 0;
    						G = 0;
    						B = 0;
    					}
    					else if( inRect( mouseKoord, whiteColor ) )
    					{
    
    					}
    					else if( inRect( mouseKoord, smallSize ) )
    					{
    						DeleteObject( aktPen );
    						*aktPen = CreatePen( PS_SOLID, 1, RGB( R, G, B ) );
    					}
    					else if( inRect( mouseKoord, middleSize ) )
    					{
    						DeleteObject( aktPen );
    						*aktPen = CreatePen( PS_SOLID, 3, RGB( R, G, B ) );
    					}
    					else if( inRect( mouseKoord, bigSize ) )
    					{
    						DeleteObject( aktPen );
    						*aktPen = CreatePen( PS_SOLID, 4, RGB( R, G, B ) );
    					}
    				}
    				else
    				{
    					if( myPoint.x != -1 )
    					{
    						mousePointForPaint.x = mouseKoord.X;
    						mousePointForPaint.y = mouseKoord.Y;
    						InvalidateRect( myWnd, NULL, TRUE);	//send WM_PAINT so that the painting is just standing, if the window will be resized
    						myPoint.x = mouseKoord.X;					//set new coordinates
    						myPoint.y = mouseKoord.Y;
    					}
    					else
    					{
    						myPoint.x = mouseKoord.X;//The first coordinates
    						myPoint.y = mouseKoord.Y;
    					}
    				}
    				visitMsg = TRUE;
    			}
    			ReleaseDC( myWnd, myHdc );
    		break;
    		case WM_LBUTTONUP:
    			myPoint.x = -1;
    			myPoint.y = -1;
    
    			visitMsg = TRUE;
    		break;
    		case WM_RBUTTONDOWN:
    			DeleteObject( whitePen );
    			DeleteObject( blackPen );
    			setGlobalVars();
    			InvalidateRect(
    							myWnd,
    							NULL,
    							TRUE
    			);
    
    			visitMsg = TRUE;
    		break;
    		case WM_MOUSEPOS:	//this message where send by the program on its own. So the program can recognize if the user is above the close-button
    			if( inRect( mouseKoord, closeButton ) )
    			{
    				if( realClose )
    				{
    					SendMessage( myAppWnd, WM_DESTROY, 0, 0 );	//close the Program
    				}
    				else
    				{
    					_beginthread( waitForClose, 0, NULL );		//you have to be 500ms over the X until the program really close
    				}
    			}
    			visitMsg = TRUE;
    		break;
    		case WM_DESTROY:
    			//Konsole wieder Sichtbar machen (soll in eigentlichem Programm auch beendet werden)
    			ShowWindow( myConsole, SW_SHOWNOACTIVATE );
    			//SendMessage( myConsole, WM_CLOSE, 0, 0 );
    			PostQuitMessage( 0 );
    		break;
    		default:
    		break;
    	}
    
    	if( visitMsg )
    		return 0;
    	else
    		return DefWindowProc( myWnd, givenMessage, wParam, lParam );
    }
    
    void setGlobalVars( void )
    {
    	int i,
    		j,
    		lastHist;
    
    	setRect(
    			&closeButton,	//RECT to set
    			0,				//begin X		(left)
    			15,				//end X		(right)
    			0,				//begin Y		(top)
    			15				//end Y		(bottom)
    	);
    	setRect( &blackColor, 0, 15, 15, 30 );//können wohl auch bald weichen
    	setRect( &whiteColor, 0, 15, 30, 45 );//aufgrund der buttons
    	setRect( &smallSize, 0, 15, 50, 65 );
    	setRect( &middleSize, 0, 15, 70, 85 );
    	setRect( &bigSize, 0, 15, 90, 105 );
    
    	whitePen = CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) );
    	blackPen = CreatePen( PS_SOLID, 1, RGB( 0, 0, 0 ) );
    
    	R = 0;
    	G = 0;
    	B = 0;
    
    	aktPen = &blackPen;
    	realClose = FALSE;
    }
    

    Ist viel Code, aber ich glaube ihr braucht nicht alles.

    Das was ihr NICHT beachten müsst habe ich schon markiert, vorher waren noch gar keine buttons drinne, sondern lediglich bestimmte bereiche im Form markiert, bei denen ich dann irgenwelche aktionen ausgeführt hatte, wenn die maus drüber war, das soll jetzt auf Buttons umgelegt werden.

    Wie gesagt, bei ButtonUp bleibt, je nach pinselbreite, ein fleck über.

    DANKE euch...



  • Elektronix schrieb:

    Sorry- aber das wird ja immer !=besser...

    Wenn dass schlechter hießen soll, kannst du da bitte genauer werden, damit ich eine chance habe ein !(!=besser) draus zu machen 🤡 😉

    Genau das versuche ich hier, mein Guter. Aber es ist unmöglich, Dir in diesem Forum alle Feinheiten der WinAPI- z. b. den Unterschied zwischen einem Button und einem Static Control mit Notyfies- zu erklären. Deswegen, zum xten mal: Nimm Dir die Tutorials vor. Und lies ggf. den Petzold.



  • Petzold? Was ist das?

    Ich habe es nun hinbekommen, ich kann in WM_PAINT malen und alles bleibt erhalten.
    Eigentlich relativ einfach:

    struct paintHist
    {
    	POINT pointToPaint;
    	int cRed;
    	int cYellow;
    	int cBlue;
    	int width;
    	struct paintHist *next;
    };
    

    Da klappt zwar das mit der Breite noch nicht, und dass mit den Farben geht auch noch nicht, aber das wird schon noch erledigt, weiß schon wo der fehler liegt.

    Ich werde jetzt ein wenig umschreiben (der performance halber) damit ich nicht bei jedem durchlauf WM_PAINT aufrufe... ich werde einfach alles in der verketteten liste speichern,
    und bei WM_PAINT alles neu aufzeichnen. 😉

    Ist performant besser oder?!



  • lippoliv schrieb:

    Petzold? Was ist das?

    Charles Petzold: "Windows-Programmierung"
    http://www.amazon.de/Windows-Programmierung-Das-Entwicklerhandbuch-zur-WIN32-API/dp/3860631888
    ist sozusagen ein Standardwerk für WinAPI-Progger, auch wenn es schon etwas älter ist.

    Ich habe es nun hinbekommen, ich kann in WM_PAINT malen und alles bleibt erhalten.
    Eigentlich relativ einfach:

    struct paintHist
    {
    	POINT pointToPaint;
    	int cRed;
    	int cYellow;
    	int cBlue;
    	int width;
    	struct paintHist *next;
    };
    

    Da klappt zwar das mit der Breite noch nicht, und dass mit den Farben geht auch noch nicht, aber das wird schon noch erledigt, weiß schon wo der fehler liegt.

    I ch werde jetzt ein wenig umschreiben (der performance halber) damit ich nicht bei jedem durchlauf WM_PAINT aufrufe... ich werde einfach alles in der verketteten liste speichern,
    und bei WM_PAINT alles neu aufzeichnen. 😉

    Ist performant besser oder?!

    Na bitte, was lange gährt...:D



  • Danke.

    Problem:
    Wenn ich Weiß in Stärke 1, 3 und 5 px und Schwar in Stärke 1, 3 und 5 px im bild habe,
    ein wenig male... und dann paar mal -schneller- hintereinander RECHTSKLICK mache, also bild resetten, verschwinden die Formatiereungen.

    Meine Struktur

    struct paintHist
    {
    	POINT pointToPaint;
    	int cRed;
    	int cYellow;
    	int cBlue;
    	int width;
    	BOOL isBreak;
    	struct paintHist *next;
    };
    

    WndProc

    LRESULT CALLBACK WndProc( HWND myWnd, UINT givenMessage, WPARAM wParam, LPARAM lParam )
    /*
    	This function recieves the Messages, wich are given from MS-Windows to the program.
    	So the program can do message specific actions, if this message is incoming.
    */
    {
    	PAINTSTRUCT myPaint;
    	//Handle für Gerätekontext(gültiger Zeichenbereich)
    	BOOL visitMsg = FALSE;
    
    	static POINT myPoint,
    				 mousePointForPaint;
    
    	static RECT myRect,
    				parent;
    
    	static COORD mouseKoord;
    
    	HANDLE backUp;
    
    	char version[50];
    
    	struct paintHist *akt;
    
    	if( LOWORD(lParam) != 0 || HIWORD(lParam) != 0)
    	{
    		mouseKoord.X = LOWORD(lParam);	//took the mouse-coordinates into a COORD variable (perfomance)
    		mouseKoord.Y = HIWORD(lParam);
    	}
    
    	switch( givenMessage )
    	{
    		case WM_CREATE:
    			myPoint.x = -1;
    			myPoint.y = -1;
    
    			GetClientRect( myAppWnd, &parent );
    
    			bClose = CreateWindow( "BUTTON", "Close", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top, 50, 20, myWnd, (HMENU)CLOSE, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			bBlack = CreateWindow( "BUTTON", "black", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+30, 50, 20, myWnd, (HMENU)cBLACK, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			bWhite = CreateWindow( "BUTTON", "white", SS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+50, 50, 20, myWnd, (HMENU)cWHITE, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    
    			strcpy( version, "Version: " );
    			strcat( version, VERSION );
    
    			versionWnd = CreateWindow( "STATIC", version, WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left+630, parent.bottom+555, 165, 20, myWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			bSmall = CreateWindow( "BUTTON", " 1px", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+75, 40, 22, myWnd, (HMENU)sSMALL, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			bMiddle = CreateWindow( "BUTTON", " 3px", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+97, 40, 22, myWnd, (HMENU)sMIDDLE, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			bBig = CreateWindow( "BUTTON", " 5px", WS_CHILD | WS_VISIBLE | WS_DLGFRAME , parent.left, parent.top+119, 40, 22, myWnd, (HMENU)sBIG, ((LPCREATESTRUCT)lParam)->hInstance, NULL );
    
    			visitMsg = TRUE;
    		break;
    		case WM_SIZE:
    			myRect.left = 0;
    			myRect.top = 0;
    			myRect.bottom = HIWORD( lParam );
    			myRect.right = LOWORD( lParam );
    
    			visitMsg = TRUE;
    		break;
    		case WM_PAINT:
    			myHdc = BeginPaint( myWnd, &myPaint );	//open device-context (paintplace)
    			{
    				backUp = SelectObject( myHdc, *aktPen );
    
    				akt = first;
    				while( NULL != akt->next )
    				{
    					if( akt->isBreak != TRUE )
    					{
    						DeleteObject( aktPen );
    						*aktPen = 	CreatePen(
    											PS_SOLID,
    											akt->width,
    											RGB( 
    												akt->cRed,
    												akt->cYellow,
    												akt->cBlue
    											)
    									);
    
    						SelectObject( myHdc, *aktPen );
    
    						MoveToEx(
    							myHdc,					//Zeichenfläche
    							akt->pointToPaint.x,	//X-Koordinate
    							akt->pointToPaint.y,	//Y-Koordinate
    							NULL					//old-Koordinate
    						);
    						LineTo(
    							myHdc,		//Zeichenfläche
    							akt->next->pointToPaint.x,	//X-Koordinate
    							akt->next->pointToPaint.y	//Y-Koordinate
    						);
    					}
    
    					akt = akt->next;
    				}
    				SelectObject( myHdc, backUp );
    			}
    			EndPaint( myWnd, &myPaint );
    			visitMsg = TRUE;
    		break;
    		case WM_MOUSEMOVE:
    			myHdc = GetDC( myWnd );			//open device-context (paintplace)
    			{
    				if( wParam == MK_LBUTTON )
    				{
    					if( myPoint.x != -1 )
    					{
    						myPoint.x = mouseKoord.X;	//set new coordinates
    						myPoint.y = mouseKoord.Y;
    
    						akt = last;
    						if( NULL == first->next )
    						{
    							akt = first;
    							akt->pointToPaint.x = myPoint.x;
    							akt->pointToPaint.y = myPoint.y;
    							akt->cRed = R;
    							akt->cYellow = G;
    							akt->cBlue = B;
    							akt->width = aktWidth;
    							akt->next = NULL;
    							last = akt;
    						}
    						if( NULL != ( akt->next = malloc( sizeof( struct paintHist ) ) ) )
    						{
    							if( last->isBreak != TRUE )
    							{
    								backUp = SelectObject( myHdc, *aktPen );
    								MoveToEx(
    									myHdc,					//Zeichenfläche
    									last->pointToPaint.x,	//X-Koordinate
    									last->pointToPaint.y,	//Y-Koordinate
    									NULL					//old-Koordinate
    								);
    								LineTo(
    									myHdc,		//Zeichenfläche
    									myPoint.x,	//X-Koordinate
    									myPoint.y	//Y-Koordinate
    								);
    								SelectObject( myHdc, backUp );
    							}
    							akt = akt->next;
    							akt->pointToPaint.x = myPoint.x;
    							akt->pointToPaint.y = myPoint.y;
    							akt->cRed = R;
    							akt->cYellow = G;
    							akt->cBlue = B;
    							akt->width = aktWidth;
    							akt->next = NULL;
    							last = akt;
    						}
    						//InvalidateRect( myWnd, NULL, TRUE);
    					}
    					else
    					{
    						myPoint.x = mouseKoord.X;//The first coordinates
    						myPoint.y = mouseKoord.Y;
    					}
    				}
    				visitMsg = TRUE;
    			}
    			ReleaseDC( myWnd, myHdc );
    		break;
    		case WM_LBUTTONUP:
    			akt = last;
    			if( NULL != ( akt->next = malloc( sizeof( struct paintHist ) ) ) )
    			{
    				akt = akt->next;
    				akt->pointToPaint.x = myPoint.x;
    				akt->pointToPaint.y = myPoint.y;
    				akt->cRed = R;
    				akt->cYellow = G;
    				akt->cBlue = B;
    				akt->width = aktWidth;
    				akt->next = NULL;
    				akt->isBreak = TRUE;
    				last = akt;
    			}
    
    			myPoint.y = -1;
    			myPoint.x = -1;
    
    			visitMsg = TRUE;
    		break;
    		case WM_RBUTTONDOWN:
    			DeleteObject( whitePen );
    			DeleteObject( blackPen );
    
    			setGlobalVars();
    
    			InvalidateRect(
    						myWnd,
    						NULL,
    						TRUE
    			);
    
    			visitMsg = TRUE;
    		break;
    		case WM_COMMAND:
    			switch( LOWORD(wParam) )
    			{
    				case CLOSE:
    					SendMessage( myAppWnd, WM_DESTROY, 0, 0 );
    
    					visitMsg = TRUE;
    				break;
    				case cWHITE:
    					aktPen = &whitePen;//slect white pen
    
    					R = 255;
    					G = 255;
    					B = 255;
    
    					visitMsg = TRUE;
    				break;
    				case cBLACK:
    					aktPen = &blackPen;//slect white pen
    
    					R = 0;
    					G = 0;
    					B = 0;
    
    					visitMsg = TRUE;
    				break;
    				case sSMALL:
    					DeleteObject( aktPen );
    					*aktPen = CreatePen( PS_SOLID, 1, RGB( R, G, B ) );
    					aktWidth = 1;
    
    					visitMsg = TRUE;
    				break;
    				case sMIDDLE:
    					DeleteObject( aktPen );
    					*aktPen = CreatePen( PS_SOLID, 3, RGB( R, G, B ) );
    					aktWidth = 3;
    
    					visitMsg = TRUE;
    				break;
    				case sBIG:
    					DeleteObject( aktPen );
    					*aktPen = CreatePen( PS_SOLID, 5, RGB( R, G, B ) );
    					aktWidth = 5;
    
    					visitMsg = TRUE;
    				break;
    				default:
    					;
    				break;
    			}
    		break;
    		case WM_DESTROY:
    			ShowWindow( myConsole, SW_SHOWNOACTIVATE );
    			//SendMessage( myConsole, WM_CLOSE, 0, 0 );
    			PostQuitMessage( 0 );
    		break;
    		default:
    		break;
    	}
    
    	if( visitMsg )
    		return 0;
    	else
    		return DefWindowProc( myWnd, givenMessage, wParam, lParam );
    }
    

    Globale Variablen:

    //Globale Variablen
    HINSTANCE myHandleInst;
    HWND myConsole,
    	 myAppWnd,
    	 bClose,
    	 bBlack,
    	 bWhite,
    	 versionWnd,
    	 bSmall,
    	 bMiddle,
    	 bBig;
    HPEN whitePen,
    	 blackPen;
    HPEN *aktPen;
    HDC myHdc;
    int R,
    	G,
    	B,
    	aktWidth;
    

    Ich verstehe dass nicht, aber eventuell Ihr...

    DANKe für alle bisherigen Posts und die Gedult.


Anmelden zum Antworten