L
MFK schrieb:
Ich auch nicht. Dein Code ist nämlich ein ziemlich undurchsichtiges Kuddelmuddel, wenn ich mal so sagen darf. Da ist viel unnötiger Ballast drin, der die Fehlersuche erschwert. Wenn du das so lassen willst, bitte sehr.
Hab ich nie behauptet.. Immer her mit sachen wie "das kann raus... Weil," ich bin schließlich kein Profi sondern lerne lediglich, und will natürlich dem entsprechend besser werden.
Nur die sache mit dem WM_PAINT fand ich einfach inakzeptabel. Ich könnte mit viel aufwand alles wieder so hin bekommen, aber es ist halt echt schlecht, weil während des malens das Form ... ja "zuckt" oder so.... Schau dir GIMP oder Paint an, da zuckts nirgends.
Ich neige schnell dazu kuddelmuddel zu schreiben, liegt daran das das nie jemand anmerkt/ich noch nicht weiß wie manche sachen einfacher gehen, als z.B. mit einer Boolvariable.
MFG
[edit] ich habe keinen debugger....
#define WINVER 0x0600
#include <windows.h>
//defines
#define appName "myPaint"
#define appTitle "myPaint, draw a Picture"
#define WM_MOUSEPOS 2954
#define histLength 100
#define CLOSE 1
#define cBLACK 2
#define cWHITE 3
#define sSMALL 4
#define sMIDDLE 5
#define sBIG 6
#define VERSION "1.20.77.080131"
//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;
struct paintHist
{
POINT pointToPaint;
int cRed;
int cYellow;
int cBlue;
int width;
BOOL isBreak;
struct paintHist *next;
};
struct paintHist *first;
struct paintHist *last;
//Funktionsprototypen
void setGlobalVars( void );
BOOL regApp( void );
BOOL createMainWindow( int );
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
//BeginOfProgramm
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
/*
Autor: Oliver Lippert
Begin: 2008-01-28
End: ==============
Description:
I want to make a program like Paint.
You have colors, different sizes and you can delete your last step
*/
{
MSG myWndMsg; //zur übermittlung von Messages die an mein programm gehen
myHandleInst = hInstance; //das Handle der Instanz wird global benötigt, da es nicht mit parametern übergeben werden kann
int returnValue = 1;
myConsole = GetConsoleWindow();
setGlobalVars();
if( NULL != ( first = malloc( sizeof( struct paintHist ) ) ) )
{
first->next = NULL;
last = first;
ShowWindow( myConsole, SW_HIDE );
if( !regApp() || !createMainWindow( nCmdShow ) ) //Fenster Registrieren und Hauptfenster erstellen
returnValue = 0;
while( GetMessage( &myWndMsg, NULL, 0, 0 ) ) //Auf Nachricht warten(muss in jedes Windows-Programm)
{
TranslateMessage( &myWndMsg ); //Übersetzt von "Virtual Key" zu "Character" message
DispatchMessage( &myWndMsg ); //Bearbeitet die Message(std oder nach WndProc())
}
}
else
returnValue = -1;
DeleteObject( blackPen );
DeleteObject( whitePen );
if( 1 != returnValue )
return myWndMsg.wParam;
else
return returnValue;
}
void setGlobalVars( void )
{
int i,
j;
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;
aktWidth = 1;
}
BOOL regApp( void )
/*
Register the Window-Class,
so that you can Create a window.
This function declares the 'details' of the program.
*/
{
WNDCLASSEX myWnd;
myWnd.cbSize = sizeof( WNDCLASSEX ); //size of the strucutre
//Fensterstile (darsellungs-Modus) festlegen
//HREDRAW = bei neuskalierung (breite) updaten
//VREDRAW = bei neuskalierung (höhe) updaten
myWnd.style = CS_HREDRAW | CS_VREDRAW;
myWnd.lpfnWndProc = (WNDPROC)WndProc; //if there is an incomming message
myWnd.cbClsExtra = 0; //extra memory for the class
myWnd.cbWndExtra = 0; //extra memory for the window
myWnd.hInstance = myHandleInst; //handle from that instance, wich the window belong to
myWnd.hIcon = LoadIcon( NULL, IDI_APPLICATION ); //Program icon (set to std)
myWnd.hCursor = LoadCursor( NULL, IDC_ARROW ); //the cursor, wich schould been used in this program
myWnd.hbrBackground = (HBRUSH)COLOR_GRAYTEXT; //background of the window
myWnd.lpszMenuName = NULL; //there is no menue
myWnd.lpszClassName = appName; //application name
myWnd.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); //smal Icon( eventually the tray-icon )
return RegisterClassEx( &myWnd ); //register the class, return the
}
BOOL createMainWindow( int cmdMod )
/*
This function create und show the Window
*/
{
HWND myWnd;
BOOL returnValue;
RECT parent;
myWnd = CreateWindow(
appName, //Name der Fensterklasse
appTitle, //Titel des Fensters
WS_VISIBLE, //Stil des Fensters
CW_USEDEFAULT, //Position X
CW_USEDEFAULT, //Position Y
800, //Breite
600, //Höhe
NULL, //Parent
NULL, //Menue
myHandleInst, //Handle des Programms
NULL //Zusätzliche Daten
);
if( !myWnd )
returnValue = FALSE;
else
{
myAppWnd = myWnd;
//Fenster nazeigen
ShowWindow( myWnd, SW_SHOWNORMAL );
//WM_PAINT message an Fenster senden
UpdateWindow( myWnd );
}
return returnValue;
}
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;
BYTE kBuff[255];
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->isBreak = FALSE;
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->isBreak = FALSE;
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 );
aktWidth = 1;
*aktPen = CreatePen( PS_SOLID, aktWidth, RGB( R, G, B ) );
visitMsg = TRUE;
break;
case sMIDDLE:
DeleteObject( aktPen );
aktWidth = 3;
*aktPen = CreatePen( PS_SOLID, aktWidth, RGB( R, G, B ) );
visitMsg = TRUE;
break;
case sBIG:
DeleteObject( aktPen );
aktWidth = 5;
*aktPen = CreatePen( PS_SOLID, aktWidth, RGB( R, G, B ) );
visitMsg = TRUE;
break;
default:
;
break;
}
break;
case WM_KEYDOWN:
GetKeyboardState( kBuff ); //get virtual keys
if( kBuff[VK_CONTROL]&0x80 && kBuff['Z']&0x80 ) //STRG + Z
{
akt = first;
if( akt->next != NULL )
{
while( NULL != akt->next->next )
akt = akt->next;
if( akt->next != NULL )
{
free( akt->next );
akt->next = NULL;
last = akt;
akt->isBreak = TRUE;
}
}
}
InvalidateRect( myWnd, NULL, TRUE );
visitMsg = TRUE;
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 );
}