Ims tarting with Windows programming with C++. I did this program with the help of my book, but i still have one problem. While im hlding the mouse Lbutton, if i want to continue draging it to the right or bottom sides out of the window i can, but if i want to do it to the top or left side i cant, my line instantly goes to the opposite side limit. i captured the mouse in the window so i can do this, but i still have that problem. Whats weong with my code?
Code:#include <windows.h>
#include <string>
#include <vector>
using namespace std;
//=========================================================
// Globals.
HWND ghMainWnd = 0;
HINSTANCE ghAppInst = 0;
struct Line
{
POINT p0;
POINT p1;
};
vector<Line> gLines;
Line gLine;
bool gMouseDown = false;
// Step 1: Define and implement the window procedure.
LRESULT CALLBACK
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Objects for painting.
HDC hdc = 0;
PAINTSTRUCT ps;
switch( msg )
{
// Handle left mouse button click message.
case WM_LBUTTONDOWN:
// Capture the mouse (we still get mouse input
// even after the mouse cursor moves off the client area.
SetCapture(hWnd);
gMouseDown = true;
// Point that was clicked is stored in the lParam.
gLine.p0.x = LOWORD(lParam);
gLine.p0.y = HIWORD(lParam);
return 0;
// Message sent whenever the mouse moves.
case WM_MOUSEMOVE:
if( gMouseDown )
{
// Current mouse position is stored in the lParam.
gLine.p1.x = LOWORD(lParam);
gLine.p1.y = HIWORD(lParam);
InvalidateRect(hWnd, 0, true);
}
return 0;
case WM_LBUTTONUP:
// Release the captured mouse when the left mouse
// button is lifted.
ReleaseCapture();
gMouseDown = false;
// Current mouse position is stored in the lParam.
gLine.p1.x = LOWORD(lParam);
gLine.p1.y = HIWORD(lParam);
gLines.push_back( gLine );
InvalidateRect(hWnd, 0, true);
return 0;
// Handle paint message.
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
if( gMouseDown )
{
MoveToEx(hdc, gLine.p0.x, gLine.p0.y, 0);
LineTo(hdc, gLine.p1.x, gLine.p1.y);
}
for(int i = 0; i < gLines.size(); ++i)
{
MoveToEx(hdc, gLines[i].p0.x, gLines[i].p0.y, 0);
LineTo(hdc, gLines[i].p1.x, gLines[i].p1.y);
}
EndPaint(hWnd, &ps);
return 0;
// Handle key down message.
case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
DestroyWindow(ghMainWnd);
return 0;
// Handle destroy window message.
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
// Forward any other messages we didn't handle to the
// default window procedure.
return DefWindowProc(hWnd, msg, wParam, lParam);
}
// WinMain: Entry point for a Windows application.
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR cmdLine, int showCmd)
{
// Save handle to application instance.
ghAppInst = hInstance;
// Step 2: Fill out a WNDCLASS instance.
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = ghAppInst;
wc.hIcon = ::LoadIcon(0, IDI_APPLICATION);
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = "MyWndClassName";
// Step 3: Register the WNDCLASS instance with Windows.
RegisterClass( &wc );
// Step 4: Create the window, and save handle in globla
// window handle variable ghMainWnd.
ghMainWnd = ::CreateWindow("MyWndClassName", "MyWindow",
WS_OVERLAPPEDWINDOW, 200, 200, 640, 480, 0, 0,
ghAppInst, 0);
if(ghMainWnd == 0)
{
::MessageBox(0, "CreateWindow - Failed", 0, 0);
return false;
}
// Step 5: Show and update the window.
ShowWindow(ghMainWnd, showCmd);
UpdateWindow(ghMainWnd);
// Step 6: Enter the message loop and don't quit until
// a WM_QUIT message is received.
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
while( GetMessage(&msg, 0, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Return exit code back to operating system.
return (int)msg.wParam;
}