Simple issue -
Sup guys,
What's wrong in the following code? -
#include <windows.h>
#include "Resource.h"
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
HINSTANCE hInstance;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_PEN));
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
static int Draw = 0;
static POINT CursorPosition, CursorPosition2;
switch (Msg)
{
case WM_DESTROY :
PostQuitMessage(WM_QUIT);
break;
case WM_CLOSE :
DestroyWindow(hWnd);
break;
case WM_LBUTTONDOWN :
Draw = 1;
GetCursorPos(&CursorPosition);
ScreenToClient(hWnd, &CursorPosition);
break;
case WM_MOUSEMOVE :
if (Draw != 0)
{
GetCursorPos(&CursorPosition2);
ScreenToClient(hWnd, &CursorPosition2);
InvalidateRect(hWnd, NULL, true);
}
break;
case WM_LBUTTONUP :
HDC DC2;
DC2 = GetDC(hWnd);
if (Draw == 1)
{
MoveToEx(DC2, CursorPosition.x, CursorPosition.y, NULL);
LineTo(DC2, CursorPosition2.x, CursorPosition2.y);
}
ReleaseDC(hWnd, DC2);
Draw = 0;
break;
case WM_PAINT :
if (Draw != 0)
{
HDC DC;
PAINTSTRUCT PS;
DC = BeginPaint(hWnd, &PS);
if (Draw == 1)
{
MoveToEx(DC, CursorPosition.x, CursorPosition.y, NULL);
LineTo(DC, CursorPosition2.x, CursorPosition2.y);
}
EndPaint(hWnd, &PS);
}
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
It should simply create a line and that's it but why does it erase every other line? I know its because of what goes on in the mousemove message but how do I stop the problem?
Thanks.
# 1 Re: Simple issue -
What's wrong with this code!? -
#include <windows.h>
#include "Resource.h"
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
HINSTANCE hInstance;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(WindowIcon));
WndClsEx.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(WindowCursor));
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(TaskbarIcon));
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
static int Draw = 0;
static POINT CursorPosition, CursorPosition2;
static HICON Icon;
switch (Msg)
{
case WM_DESTROY :
PostQuitMessage(WM_QUIT);
break;
case WM_CLOSE :
DestroyWindow(hWnd);
break;
case WM_LBUTTONDOWN :
Draw = 1;
GetCursorPos(&CursorPosition);
ScreenToClient(hWnd, &CursorPosition);
break;
case WM_MOUSEMOVE :
if (Draw != 0)
{
GetCursorPos(&CursorPosition2);
ScreenToClient(hWnd, &CursorPosition2);
InvalidateRect(hWnd, NULL, true);
}
break;
case WM_LBUTTONUP :
HDC DC2;
Icon = LoadIcon(hInstance, MAKEINTRESOURCE(WindowIcon));
DC2 = GetDC(hWnd);
if (Draw == 1)
{
MoveToEx(DC2, CursorPosition.x, CursorPosition.y, NULL);
LineTo(DC2, CursorPosition2.x, CursorPosition2.y);
DrawIcon(DC2, 0, 0, Icon);
}
ReleaseDC(hWnd, DC2);
Draw = 0;
break;
case WM_PAINT :
if (Draw != 0)
{
HDC DC;
PAINTSTRUCT PS;
DC = BeginPaint(hWnd, &PS);
if (Draw == 1)
{
MoveToEx(DC, CursorPosition.x, CursorPosition.y, NULL);
LineTo(DC, CursorPosition2.x, CursorPosition2.y);
}
EndPaint(hWnd, &PS);
}
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
Why does it just display a question mark at the top left?
Thanks.
# 2 Re: Simple issue -
Sup guys,
What's wrong in the following code? -
#include <windows.h>
#include "Resource.h"
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
HINSTANCE hInstance;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_PEN));
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
static int Draw = 0;
static POINT CursorPosition, CursorPosition2;
switch (Msg)
{
case WM_DESTROY :
PostQuitMessage(WM_QUIT);
break;
case WM_CLOSE :
DestroyWindow(hWnd);
break;
case WM_LBUTTONDOWN :
Draw = 1;
GetCursorPos(&CursorPosition);
ScreenToClient(hWnd, &CursorPosition);
break;
case WM_MOUSEMOVE :
if (Draw != 0)
{
GetCursorPos(&CursorPosition2);
ScreenToClient(hWnd, &CursorPosition2);
InvalidateRect(hWnd, NULL, true);
}
break;
case WM_LBUTTONUP :
HDC DC2;
DC2 = GetDC(hWnd);
if (Draw == 1)
{
MoveToEx(DC2, CursorPosition.x, CursorPosition.y, NULL);
LineTo(DC2, CursorPosition2.x, CursorPosition2.y);
}
ReleaseDC(hWnd, DC2);
Draw = 0;
break;
case WM_PAINT :
if (Draw != 0)
{
HDC DC;
PAINTSTRUCT PS;
DC = BeginPaint(hWnd, &PS);
if (Draw == 1)
{
MoveToEx(DC, CursorPosition.x, CursorPosition.y, NULL);
LineTo(DC, CursorPosition2.x, CursorPosition2.y);
}
EndPaint(hWnd, &PS);
}
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
It should simply create a line and that's it but why does it erase every other line? I know its because of what goes on in the mousemove message but how do I stop the problem?
Thanks.
In WM_LBUTTONUP store each line segment in a collection. Then in WM_PAINT draw every line.
As far as the question mark goes, I would say it's because you have Windows paint the background and keeps track of the DC what needs painted or not. So in the call to InvalidateRect(), it does not send a WM_PAINT message... I would guess. Passing true to InvalidateRect()'s last parameter is for erasing... With DefWindowProc, WM_ERASEBKGND is where that GetStockObject() brush is used.
I have not run the code.
# 3 Re: Simple issue -
If you want any help, please describe the problem.
Do you have a compilation error?
Do you have a runtime error?
What's the exact error message?
...
Marc G at 2007-11-9 13:34:48 >

# 4 Re: Simple issue -
James : Can I please have an example?
Marc G : If you are talking about the second issue then there is no error but when I actually draw the line a question mark shows up at the top left of the client area, why?.
Thanks.
# 5 Re: Simple issue -
This doesn't draw while you are dragging. Although it does keep track of all segments.
#include <windows.h>
#include <vector>
struct LineSegment
{
POINT pt1;
POINT pt2;
};
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "CodeBlocksWindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Code::Blocks Template Windows App", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int Draw = 0;
static LineSegment LineObj;
static std::vector<LineSegment> Segments;
PAINTSTRUCT ps;
HDC hPaintDC;
std::vector<LineSegment>::iterator it;
switch (message) /* handle the messages */
{
case WM_LBUTTONDOWN:
::GetCursorPos(&LineObj.pt1);
::ScreenToClient(hwnd,&LineObj.pt1);
Draw = 1;
return 0;
case WM_LBUTTONUP:
if (Draw == 1)
{
::GetCursorPos(&LineObj.pt2);
::ScreenToClient(hwnd,&LineObj.pt2);
Segments.push_back(LineObj);
::RedrawWindow(hwnd,0,0,RDW_INVALIDATE | RDW_ERASE);
Draw = 0;
}
return 0;
case WM_PAINT:
hPaintDC = ::BeginPaint(hwnd,&ps);
it = Segments.begin();
while (it != Segments.end())
{
::MoveToEx(hPaintDC,it->pt1.x,it->pt1.y,0);
::LineTo(hPaintDC,it->pt2.x,it->pt2.y);
++it;
}
::EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
# 6 Re: Simple issue -
Marc G : If you are talking about the second issue then there is no error but when I actually draw the line a question mark shows up at the top left of the client area, why?
Please post a screenshot.
Marc G at 2007-11-9 13:37:50 >

# 7 Re: Simple issue -
James : Isn't there any other method? I don't even understand what just happened!
Marc G : Mind WinSpy++ :p -
Thanks.
# 8 Re: Simple issue -
That's strange, since you are not drawing any icons... Are you sure you pasted the correct code in your post? Is it possible to post the full project? Please remove any temporary files like .ncb.
Marc G at 2007-11-9 13:39:56 >

# 9 Re: Simple issue -
In the second problem I am drawing an image but the wrong one comes up - check it out(Borland C++ Builder 6) -
# 10 Re: Simple issue -
Problem might be because your icon is 16x16. According to MSDN:
LoadIcon can only load an icon whose size conforms to the SM_CXICON and SM_CYICON system metric values. Use the LoadImage function to load icons of other sizes..
So try, LoadImage instead.
Marc G at 2007-11-9 13:41:54 >

# 11 Re: Simple issue -
Grrr, it still did not work :( - here's the updaed code -
#include <windows.h>
#include "Resource.h"
const char *ClsName = "BasicApp";
const char *WndName = "A Simple Window";
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
HINSTANCE hInstance;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProc;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(WindowIcon));
WndClsEx.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(WindowCursor));
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(TaskbarIcon));
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Find out if the window was created
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Display the window to the user
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// Decode and treat the messages
// as long as the application is running
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
static int Draw = 0;
static POINT CursorPosition, CursorPosition2;
static HANDLE Icon;
switch (Msg)
{
case WM_DESTROY :
PostQuitMessage(WM_QUIT);
break;
case WM_CLOSE :
DestroyWindow(hWnd);
break;
case WM_LBUTTONDOWN :
Draw = 1;
GetCursorPos(&CursorPosition);
ScreenToClient(hWnd, &CursorPosition);
break;
case WM_MOUSEMOVE :
if (Draw != 0)
{
GetCursorPos(&CursorPosition2);
ScreenToClient(hWnd, &CursorPosition2);
InvalidateRect(hWnd, NULL, true);
}
break;
case WM_LBUTTONUP :
HDC DC2;
Icon = LoadImage(hInstance, MAKEINTRESOURCE(WindowIcon), IMAGE_ICON, 300, 300, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
DC2 = GetDC(hWnd);
if (Draw == 1)
{
MoveToEx(DC2, CursorPosition.x, CursorPosition.y, NULL);
LineTo(DC2, CursorPosition2.x, CursorPosition2.y);
DrawIcon(DC2, 0, 0, Icon);
}
ReleaseDC(hWnd, DC2);
Draw = 0;
break;
case WM_PAINT :
if (Draw != 0)
{
HDC DC;
PAINTSTRUCT PS;
DC = BeginPaint(hWnd, &PS);
if (Draw == 1)
{
MoveToEx(DC, CursorPosition.x, CursorPosition.y, NULL);
LineTo(DC, CursorPosition2.x, CursorPosition2.y);
}
EndPaint(hWnd, &PS);
}
break;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
Thanks.
# 12 Re: Simple issue -
One thing I can tell you without running this code.
LoadImage() could be used just once to get a handle to the icon. (you do not have to load the image every time WM_LBUTTONUP is handled.
Second of all, LoadImage() passed with the LR_DEFAULTSIZE flag tries to create an image of the specified type with the TYPE's default size. Not the default size of the image.
To get the default size of the image, you pass 0 to both parameters on size.
If you pass parameters to LoadImage() for it's dimensions, LoadImage() can fail because it will only resize images to 'standard' defined dimensions. (In my experience)
# 13 Re: Simple issue -
LoadImage() could be used just once to get a handle to the icon. (you do not have to load the image every time WM_LBUTTONUP is handled.
I know. The reason I do it is because when it works once I like to do it again, sort of like a mini party or hooray :)
As for the rest its the first time I used the function...
Are there any ideas for why that unusual image pops up?
Thanks.
# 14 Re: Simple issue -
Did you try to specify 0 as width and height and remove the LR_DEFAULTSIZE flag as James told you?
Marc G at 2007-11-9 13:45:59 >

# 15 Re: Simple issue -
Yip I did :( and it had the same results.