draw line doesn't work, what might be the problem?PeekMessage problemAPI-level Unicode GUI Native apps in C++ for Windows/Linux/MacWhy is wparam changing if i use same message, with same paras?SendMessage(hwnd, registeredmssghere, 0, 1) received but not correctly recognized by hooked thread its sent to!global pointers to objects will break program by access violation when accessing object attributes/methods through themC2440 Can't convert LRESULT to WNDPROC in C++ WinApiSubclassing an edit text control to accept lowercase characters when shift is pressedProblems with a window event callback function C++Direct2D WM_MOUSEMOVE message with scaled displayWindows freezes after trying to render triangle in directx11

What happened to Hopper's girlfriend in season one?

How can I prevent a user from copying files on another hard drive?

How does DC work with natural 20?

Is there a name for the trope when there is a moments dialogue when someone pauses just before they leave the room?

How do internally carried IR missiles acquire a lock?

What is the "ls" directory in my home directory?

How do I remove this inheritance-related code smell?

What mathematical theory is required for high frequency trading?

What constitutes a syllable?

Print one file per line using echo

What is the highest voltage from the power supply a Raspberry Pi 3 B can handle without getting damaged?

Too early in the morning to have SODA?

Why isn't it a compile-time error to return a nullptr as a std::string?

Greeting with "Ho"

Umlaut character order when sorting

Improve appearance of the table in Latex

How long did the SR-71 take to get to cruising altitude?

Why isn't my calculation that we should be able to see the sun well beyond the observable universe valid?

Did the CIA blow up a Siberian pipeline in 1982?

Where should a runway for a spaceplane be located?

Draw a symmetric alien head

I just entered the USA without passport control at Atlanta airport

Extending prime numbers digit by digit while retaining primality

How hard is it to distinguish if I am given remote access to a virtual machine vs a piece of hardware?



draw line doesn't work, what might be the problem?


PeekMessage problemAPI-level Unicode GUI Native apps in C++ for Windows/Linux/MacWhy is wparam changing if i use same message, with same paras?SendMessage(hwnd, registeredmssghere, 0, 1) received but not correctly recognized by hooked thread its sent to!global pointers to objects will break program by access violation when accessing object attributes/methods through themC2440 Can't convert LRESULT to WNDPROC in C++ WinApiSubclassing an edit text control to accept lowercase characters when shift is pressedProblems with a window event callback function C++Direct2D WM_MOUSEMOVE message with scaled displayWindows freezes after trying to render triangle in directx11






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















I want to draw the line by clicking the mouse on the first coordinate where the line should start and second coordinate where the line should end.
When I run my project nothing happens.
I cannot find out what my code is missing.



LONG WINAPI WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)


HDC hdc;
BOOL fDraw = FALSE;
POINT ptPrevious = 0 ;
HPEN Pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 255));


switch (Message)
case WM_LBUTTONDOWN:
fDraw = TRUE;
ptPrevious.x = LOWORD(lParam);
ptPrevious.y = HIWORD(lParam);
break;


case WM_LBUTTONUP:
if (fDraw)

hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
ReleaseDC(hWnd, hdc);

fDraw = FALSE;
break;



case WM_MOUSEMOVE:
if (fDraw)

hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, ptPrevious.x = LOWORD(lParam),
ptPrevious.y = HIWORD(lParam));
ReleaseDC(hWnd, hdc);

break;



case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hWnd, Message, wParam, lParam);

return 0;










share|improve this question






















  • Draw to an off screen bitmap, and then paint it to screen WM_PAINT.

    – David Heffernan
    Mar 24 at 11:57

















1















I want to draw the line by clicking the mouse on the first coordinate where the line should start and second coordinate where the line should end.
When I run my project nothing happens.
I cannot find out what my code is missing.



LONG WINAPI WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)


HDC hdc;
BOOL fDraw = FALSE;
POINT ptPrevious = 0 ;
HPEN Pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 255));


switch (Message)
case WM_LBUTTONDOWN:
fDraw = TRUE;
ptPrevious.x = LOWORD(lParam);
ptPrevious.y = HIWORD(lParam);
break;


case WM_LBUTTONUP:
if (fDraw)

hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
ReleaseDC(hWnd, hdc);

fDraw = FALSE;
break;



case WM_MOUSEMOVE:
if (fDraw)

hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, ptPrevious.x = LOWORD(lParam),
ptPrevious.y = HIWORD(lParam));
ReleaseDC(hWnd, hdc);

break;



case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hWnd, Message, wParam, lParam);

return 0;










share|improve this question






















  • Draw to an off screen bitmap, and then paint it to screen WM_PAINT.

    – David Heffernan
    Mar 24 at 11:57













1












1








1








I want to draw the line by clicking the mouse on the first coordinate where the line should start and second coordinate where the line should end.
When I run my project nothing happens.
I cannot find out what my code is missing.



LONG WINAPI WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)


HDC hdc;
BOOL fDraw = FALSE;
POINT ptPrevious = 0 ;
HPEN Pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 255));


switch (Message)
case WM_LBUTTONDOWN:
fDraw = TRUE;
ptPrevious.x = LOWORD(lParam);
ptPrevious.y = HIWORD(lParam);
break;


case WM_LBUTTONUP:
if (fDraw)

hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
ReleaseDC(hWnd, hdc);

fDraw = FALSE;
break;



case WM_MOUSEMOVE:
if (fDraw)

hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, ptPrevious.x = LOWORD(lParam),
ptPrevious.y = HIWORD(lParam));
ReleaseDC(hWnd, hdc);

break;



case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hWnd, Message, wParam, lParam);

return 0;










share|improve this question














I want to draw the line by clicking the mouse on the first coordinate where the line should start and second coordinate where the line should end.
When I run my project nothing happens.
I cannot find out what my code is missing.



LONG WINAPI WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)


HDC hdc;
BOOL fDraw = FALSE;
POINT ptPrevious = 0 ;
HPEN Pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 255));


switch (Message)
case WM_LBUTTONDOWN:
fDraw = TRUE;
ptPrevious.x = LOWORD(lParam);
ptPrevious.y = HIWORD(lParam);
break;


case WM_LBUTTONUP:
if (fDraw)

hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
ReleaseDC(hWnd, hdc);

fDraw = FALSE;
break;



case WM_MOUSEMOVE:
if (fDraw)

hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, ptPrevious.x = LOWORD(lParam),
ptPrevious.y = HIWORD(lParam));
ReleaseDC(hWnd, hdc);

break;



case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hWnd, Message, wParam, lParam);

return 0;







c++ winapi






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 24 at 10:44









AndrewAndrew

478314




478314












  • Draw to an off screen bitmap, and then paint it to screen WM_PAINT.

    – David Heffernan
    Mar 24 at 11:57

















  • Draw to an off screen bitmap, and then paint it to screen WM_PAINT.

    – David Heffernan
    Mar 24 at 11:57
















Draw to an off screen bitmap, and then paint it to screen WM_PAINT.

– David Heffernan
Mar 24 at 11:57





Draw to an off screen bitmap, and then paint it to screen WM_PAINT.

– David Heffernan
Mar 24 at 11:57












3 Answers
3






active

oldest

votes


















1














Because declared variables are local variables, variables can be declared with Static.



 static BOOL fDraw = FALSE;
static POINT ptPrevious = 0 ;


In addition, you forget to use the SelectObject function to select pen into DC.



You can also use WM_PAINT redrawing to improve your code:



Example:



 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

HDC hdc;
PAINTSTRUCT ps;
static BOOL fDraw = FALSE;
static BOOL fDraw_begin = FALSE;
static POINT ptPrevious;
static RECT rcClient;
static POINT pt;
static HPEN Pen;

switch (message)

case WM_CREATE:

Pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
break;


case WM_LBUTTONDOWN:

ptPrevious.x = (LONG)LOWORD(lParam);
ptPrevious.y = (LONG)HIWORD(lParam);
return 0;


case WM_LBUTTONUP:

if (fDraw = TRUE)

fDraw = FALSE;
fDraw_begin = TRUE;
InvalidateRect(hwnd, &rcClient, TRUE);
UpdateWindow(hwnd);


return 0;


case WM_MOUSEMOVE:

if (wParam && MK_LBUTTON)

GetClientRect(hwnd, &rcClient);
hdc = GetDC(hwnd);
SetROP2(hdc, R2_NOTXORPEN);
if (!IsRectEmpty(&rcClient)) // Detecting whether the rectangular area is empty

MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, (LONG)LOWORD(lParam),
(LONG)HIWORD(lParam));

MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, (LONG)LOWORD(lParam),
(LONG)HIWORD(lParam));
pt.x = (LONG)LOWORD(lParam);
pt.y = (LONG)HIWORD(lParam);
fDraw = TRUE;

ReleaseDC(hwnd, hdc);

return 0;


case WM_PAINT:

hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, Pen);
if (fDraw_begin)

fDraw_begin = FALSE;
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, pt.x,
pt.y);

EndPaint(hwnd, &ps);
ReleaseDC(hwnd, hdc);
return 0;


case WM_DESTROY:

DeleteObject(Pen);
PostQuitMessage(0);
return 0;



return DefWindowProc(hwnd, message, wParam, lParam);






share|improve this answer
































    2














    Fundamentally, the problem is because none of your data is persistent. Since they are all local variables, their content disappears when WndProc returns. fDraw is set to FALSE on every message, and will never be true for the WM_LBUTTONDOWN or WM_MOUSEMOVE messages. Therefore nothing happens.



    You'll want to create some sort of a class to hold fDraw, ptPrevious, and a structure to hold the coordinates of the line(s) to draw. Use InvalidateRect in the WM_MOUSEMOVE and WM_LBUTTONUP messages. Then only draw them in response to a WM_PAINT message (using the DC provided in the paint message).



    Using the CWnd MFC class can greatly simplify those tasks.






    share|improve this answer






























      1














      Do not get the DC three times, get it once and release it on mouse up.
      Also, your drawing will be eventually validated, so you need to log the mouse move and repeat this stuff in WM_PAINT handler.






      share|improve this answer























      • so can i declare DC outside switch statement? can i just use WM_PAINT instead of WM_MOUSEMOVE?

        – Andrew
        Mar 24 at 10:54











      • In generic Windows apps, drawing is done in response to WM_PAINT. Drawing does not persist. This means that if your window is minimized, the next maximize won't show what you have drawn previously. That's why you draw it when Windows requests it, that is, in WM_PAINT. When doing real time drawing, you can use GetDC() to get the DC, but also you save what you have drawn (in your case, the start/end xy), and repeat it with a memory DC in response to WM_PAINT. So you can use GetDC() on WM_LBUTTONDOWN, but save the dc until WM_LBUTTONUP. Then log what you have drawn to redraw it in WM_PAINT.

        – Michael Chourdakis
        Mar 24 at 11:09












      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55322969%2fdraw-line-doesnt-work-what-might-be-the-problem%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      Because declared variables are local variables, variables can be declared with Static.



       static BOOL fDraw = FALSE;
      static POINT ptPrevious = 0 ;


      In addition, you forget to use the SelectObject function to select pen into DC.



      You can also use WM_PAINT redrawing to improve your code:



      Example:



       LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

      HDC hdc;
      PAINTSTRUCT ps;
      static BOOL fDraw = FALSE;
      static BOOL fDraw_begin = FALSE;
      static POINT ptPrevious;
      static RECT rcClient;
      static POINT pt;
      static HPEN Pen;

      switch (message)

      case WM_CREATE:

      Pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
      break;


      case WM_LBUTTONDOWN:

      ptPrevious.x = (LONG)LOWORD(lParam);
      ptPrevious.y = (LONG)HIWORD(lParam);
      return 0;


      case WM_LBUTTONUP:

      if (fDraw = TRUE)

      fDraw = FALSE;
      fDraw_begin = TRUE;
      InvalidateRect(hwnd, &rcClient, TRUE);
      UpdateWindow(hwnd);


      return 0;


      case WM_MOUSEMOVE:

      if (wParam && MK_LBUTTON)

      GetClientRect(hwnd, &rcClient);
      hdc = GetDC(hwnd);
      SetROP2(hdc, R2_NOTXORPEN);
      if (!IsRectEmpty(&rcClient)) // Detecting whether the rectangular area is empty

      MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
      LineTo(hdc, (LONG)LOWORD(lParam),
      (LONG)HIWORD(lParam));

      MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
      LineTo(hdc, (LONG)LOWORD(lParam),
      (LONG)HIWORD(lParam));
      pt.x = (LONG)LOWORD(lParam);
      pt.y = (LONG)HIWORD(lParam);
      fDraw = TRUE;

      ReleaseDC(hwnd, hdc);

      return 0;


      case WM_PAINT:

      hdc = BeginPaint(hwnd, &ps);
      SelectObject(hdc, Pen);
      if (fDraw_begin)

      fDraw_begin = FALSE;
      MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
      LineTo(hdc, pt.x,
      pt.y);

      EndPaint(hwnd, &ps);
      ReleaseDC(hwnd, hdc);
      return 0;


      case WM_DESTROY:

      DeleteObject(Pen);
      PostQuitMessage(0);
      return 0;



      return DefWindowProc(hwnd, message, wParam, lParam);






      share|improve this answer





























        1














        Because declared variables are local variables, variables can be declared with Static.



         static BOOL fDraw = FALSE;
        static POINT ptPrevious = 0 ;


        In addition, you forget to use the SelectObject function to select pen into DC.



        You can also use WM_PAINT redrawing to improve your code:



        Example:



         LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

        HDC hdc;
        PAINTSTRUCT ps;
        static BOOL fDraw = FALSE;
        static BOOL fDraw_begin = FALSE;
        static POINT ptPrevious;
        static RECT rcClient;
        static POINT pt;
        static HPEN Pen;

        switch (message)

        case WM_CREATE:

        Pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
        break;


        case WM_LBUTTONDOWN:

        ptPrevious.x = (LONG)LOWORD(lParam);
        ptPrevious.y = (LONG)HIWORD(lParam);
        return 0;


        case WM_LBUTTONUP:

        if (fDraw = TRUE)

        fDraw = FALSE;
        fDraw_begin = TRUE;
        InvalidateRect(hwnd, &rcClient, TRUE);
        UpdateWindow(hwnd);


        return 0;


        case WM_MOUSEMOVE:

        if (wParam && MK_LBUTTON)

        GetClientRect(hwnd, &rcClient);
        hdc = GetDC(hwnd);
        SetROP2(hdc, R2_NOTXORPEN);
        if (!IsRectEmpty(&rcClient)) // Detecting whether the rectangular area is empty

        MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
        LineTo(hdc, (LONG)LOWORD(lParam),
        (LONG)HIWORD(lParam));

        MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
        LineTo(hdc, (LONG)LOWORD(lParam),
        (LONG)HIWORD(lParam));
        pt.x = (LONG)LOWORD(lParam);
        pt.y = (LONG)HIWORD(lParam);
        fDraw = TRUE;

        ReleaseDC(hwnd, hdc);

        return 0;


        case WM_PAINT:

        hdc = BeginPaint(hwnd, &ps);
        SelectObject(hdc, Pen);
        if (fDraw_begin)

        fDraw_begin = FALSE;
        MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
        LineTo(hdc, pt.x,
        pt.y);

        EndPaint(hwnd, &ps);
        ReleaseDC(hwnd, hdc);
        return 0;


        case WM_DESTROY:

        DeleteObject(Pen);
        PostQuitMessage(0);
        return 0;



        return DefWindowProc(hwnd, message, wParam, lParam);






        share|improve this answer



























          1












          1








          1







          Because declared variables are local variables, variables can be declared with Static.



           static BOOL fDraw = FALSE;
          static POINT ptPrevious = 0 ;


          In addition, you forget to use the SelectObject function to select pen into DC.



          You can also use WM_PAINT redrawing to improve your code:



          Example:



           LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

          HDC hdc;
          PAINTSTRUCT ps;
          static BOOL fDraw = FALSE;
          static BOOL fDraw_begin = FALSE;
          static POINT ptPrevious;
          static RECT rcClient;
          static POINT pt;
          static HPEN Pen;

          switch (message)

          case WM_CREATE:

          Pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
          break;


          case WM_LBUTTONDOWN:

          ptPrevious.x = (LONG)LOWORD(lParam);
          ptPrevious.y = (LONG)HIWORD(lParam);
          return 0;


          case WM_LBUTTONUP:

          if (fDraw = TRUE)

          fDraw = FALSE;
          fDraw_begin = TRUE;
          InvalidateRect(hwnd, &rcClient, TRUE);
          UpdateWindow(hwnd);


          return 0;


          case WM_MOUSEMOVE:

          if (wParam && MK_LBUTTON)

          GetClientRect(hwnd, &rcClient);
          hdc = GetDC(hwnd);
          SetROP2(hdc, R2_NOTXORPEN);
          if (!IsRectEmpty(&rcClient)) // Detecting whether the rectangular area is empty

          MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
          LineTo(hdc, (LONG)LOWORD(lParam),
          (LONG)HIWORD(lParam));

          MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
          LineTo(hdc, (LONG)LOWORD(lParam),
          (LONG)HIWORD(lParam));
          pt.x = (LONG)LOWORD(lParam);
          pt.y = (LONG)HIWORD(lParam);
          fDraw = TRUE;

          ReleaseDC(hwnd, hdc);

          return 0;


          case WM_PAINT:

          hdc = BeginPaint(hwnd, &ps);
          SelectObject(hdc, Pen);
          if (fDraw_begin)

          fDraw_begin = FALSE;
          MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
          LineTo(hdc, pt.x,
          pt.y);

          EndPaint(hwnd, &ps);
          ReleaseDC(hwnd, hdc);
          return 0;


          case WM_DESTROY:

          DeleteObject(Pen);
          PostQuitMessage(0);
          return 0;



          return DefWindowProc(hwnd, message, wParam, lParam);






          share|improve this answer















          Because declared variables are local variables, variables can be declared with Static.



           static BOOL fDraw = FALSE;
          static POINT ptPrevious = 0 ;


          In addition, you forget to use the SelectObject function to select pen into DC.



          You can also use WM_PAINT redrawing to improve your code:



          Example:



           LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

          HDC hdc;
          PAINTSTRUCT ps;
          static BOOL fDraw = FALSE;
          static BOOL fDraw_begin = FALSE;
          static POINT ptPrevious;
          static RECT rcClient;
          static POINT pt;
          static HPEN Pen;

          switch (message)

          case WM_CREATE:

          Pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
          break;


          case WM_LBUTTONDOWN:

          ptPrevious.x = (LONG)LOWORD(lParam);
          ptPrevious.y = (LONG)HIWORD(lParam);
          return 0;


          case WM_LBUTTONUP:

          if (fDraw = TRUE)

          fDraw = FALSE;
          fDraw_begin = TRUE;
          InvalidateRect(hwnd, &rcClient, TRUE);
          UpdateWindow(hwnd);


          return 0;


          case WM_MOUSEMOVE:

          if (wParam && MK_LBUTTON)

          GetClientRect(hwnd, &rcClient);
          hdc = GetDC(hwnd);
          SetROP2(hdc, R2_NOTXORPEN);
          if (!IsRectEmpty(&rcClient)) // Detecting whether the rectangular area is empty

          MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
          LineTo(hdc, (LONG)LOWORD(lParam),
          (LONG)HIWORD(lParam));

          MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
          LineTo(hdc, (LONG)LOWORD(lParam),
          (LONG)HIWORD(lParam));
          pt.x = (LONG)LOWORD(lParam);
          pt.y = (LONG)HIWORD(lParam);
          fDraw = TRUE;

          ReleaseDC(hwnd, hdc);

          return 0;


          case WM_PAINT:

          hdc = BeginPaint(hwnd, &ps);
          SelectObject(hdc, Pen);
          if (fDraw_begin)

          fDraw_begin = FALSE;
          MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
          LineTo(hdc, pt.x,
          pt.y);

          EndPaint(hwnd, &ps);
          ReleaseDC(hwnd, hdc);
          return 0;


          case WM_DESTROY:

          DeleteObject(Pen);
          PostQuitMessage(0);
          return 0;



          return DefWindowProc(hwnd, message, wParam, lParam);







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 25 at 7:40

























          answered Mar 25 at 6:10









          Strive Sun - MSFTStrive Sun - MSFT

          41017




          41017























              2














              Fundamentally, the problem is because none of your data is persistent. Since they are all local variables, their content disappears when WndProc returns. fDraw is set to FALSE on every message, and will never be true for the WM_LBUTTONDOWN or WM_MOUSEMOVE messages. Therefore nothing happens.



              You'll want to create some sort of a class to hold fDraw, ptPrevious, and a structure to hold the coordinates of the line(s) to draw. Use InvalidateRect in the WM_MOUSEMOVE and WM_LBUTTONUP messages. Then only draw them in response to a WM_PAINT message (using the DC provided in the paint message).



              Using the CWnd MFC class can greatly simplify those tasks.






              share|improve this answer



























                2














                Fundamentally, the problem is because none of your data is persistent. Since they are all local variables, their content disappears when WndProc returns. fDraw is set to FALSE on every message, and will never be true for the WM_LBUTTONDOWN or WM_MOUSEMOVE messages. Therefore nothing happens.



                You'll want to create some sort of a class to hold fDraw, ptPrevious, and a structure to hold the coordinates of the line(s) to draw. Use InvalidateRect in the WM_MOUSEMOVE and WM_LBUTTONUP messages. Then only draw them in response to a WM_PAINT message (using the DC provided in the paint message).



                Using the CWnd MFC class can greatly simplify those tasks.






                share|improve this answer

























                  2












                  2








                  2







                  Fundamentally, the problem is because none of your data is persistent. Since they are all local variables, their content disappears when WndProc returns. fDraw is set to FALSE on every message, and will never be true for the WM_LBUTTONDOWN or WM_MOUSEMOVE messages. Therefore nothing happens.



                  You'll want to create some sort of a class to hold fDraw, ptPrevious, and a structure to hold the coordinates of the line(s) to draw. Use InvalidateRect in the WM_MOUSEMOVE and WM_LBUTTONUP messages. Then only draw them in response to a WM_PAINT message (using the DC provided in the paint message).



                  Using the CWnd MFC class can greatly simplify those tasks.






                  share|improve this answer













                  Fundamentally, the problem is because none of your data is persistent. Since they are all local variables, their content disappears when WndProc returns. fDraw is set to FALSE on every message, and will never be true for the WM_LBUTTONDOWN or WM_MOUSEMOVE messages. Therefore nothing happens.



                  You'll want to create some sort of a class to hold fDraw, ptPrevious, and a structure to hold the coordinates of the line(s) to draw. Use InvalidateRect in the WM_MOUSEMOVE and WM_LBUTTONUP messages. Then only draw them in response to a WM_PAINT message (using the DC provided in the paint message).



                  Using the CWnd MFC class can greatly simplify those tasks.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 24 at 17:27









                  1201ProgramAlarm1201ProgramAlarm

                  20.1k72741




                  20.1k72741





















                      1














                      Do not get the DC three times, get it once and release it on mouse up.
                      Also, your drawing will be eventually validated, so you need to log the mouse move and repeat this stuff in WM_PAINT handler.






                      share|improve this answer























                      • so can i declare DC outside switch statement? can i just use WM_PAINT instead of WM_MOUSEMOVE?

                        – Andrew
                        Mar 24 at 10:54











                      • In generic Windows apps, drawing is done in response to WM_PAINT. Drawing does not persist. This means that if your window is minimized, the next maximize won't show what you have drawn previously. That's why you draw it when Windows requests it, that is, in WM_PAINT. When doing real time drawing, you can use GetDC() to get the DC, but also you save what you have drawn (in your case, the start/end xy), and repeat it with a memory DC in response to WM_PAINT. So you can use GetDC() on WM_LBUTTONDOWN, but save the dc until WM_LBUTTONUP. Then log what you have drawn to redraw it in WM_PAINT.

                        – Michael Chourdakis
                        Mar 24 at 11:09
















                      1














                      Do not get the DC three times, get it once and release it on mouse up.
                      Also, your drawing will be eventually validated, so you need to log the mouse move and repeat this stuff in WM_PAINT handler.






                      share|improve this answer























                      • so can i declare DC outside switch statement? can i just use WM_PAINT instead of WM_MOUSEMOVE?

                        – Andrew
                        Mar 24 at 10:54











                      • In generic Windows apps, drawing is done in response to WM_PAINT. Drawing does not persist. This means that if your window is minimized, the next maximize won't show what you have drawn previously. That's why you draw it when Windows requests it, that is, in WM_PAINT. When doing real time drawing, you can use GetDC() to get the DC, but also you save what you have drawn (in your case, the start/end xy), and repeat it with a memory DC in response to WM_PAINT. So you can use GetDC() on WM_LBUTTONDOWN, but save the dc until WM_LBUTTONUP. Then log what you have drawn to redraw it in WM_PAINT.

                        – Michael Chourdakis
                        Mar 24 at 11:09














                      1












                      1








                      1







                      Do not get the DC three times, get it once and release it on mouse up.
                      Also, your drawing will be eventually validated, so you need to log the mouse move and repeat this stuff in WM_PAINT handler.






                      share|improve this answer













                      Do not get the DC three times, get it once and release it on mouse up.
                      Also, your drawing will be eventually validated, so you need to log the mouse move and repeat this stuff in WM_PAINT handler.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Mar 24 at 10:48









                      Michael ChourdakisMichael Chourdakis

                      3,27012042




                      3,27012042












                      • so can i declare DC outside switch statement? can i just use WM_PAINT instead of WM_MOUSEMOVE?

                        – Andrew
                        Mar 24 at 10:54











                      • In generic Windows apps, drawing is done in response to WM_PAINT. Drawing does not persist. This means that if your window is minimized, the next maximize won't show what you have drawn previously. That's why you draw it when Windows requests it, that is, in WM_PAINT. When doing real time drawing, you can use GetDC() to get the DC, but also you save what you have drawn (in your case, the start/end xy), and repeat it with a memory DC in response to WM_PAINT. So you can use GetDC() on WM_LBUTTONDOWN, but save the dc until WM_LBUTTONUP. Then log what you have drawn to redraw it in WM_PAINT.

                        – Michael Chourdakis
                        Mar 24 at 11:09


















                      • so can i declare DC outside switch statement? can i just use WM_PAINT instead of WM_MOUSEMOVE?

                        – Andrew
                        Mar 24 at 10:54











                      • In generic Windows apps, drawing is done in response to WM_PAINT. Drawing does not persist. This means that if your window is minimized, the next maximize won't show what you have drawn previously. That's why you draw it when Windows requests it, that is, in WM_PAINT. When doing real time drawing, you can use GetDC() to get the DC, but also you save what you have drawn (in your case, the start/end xy), and repeat it with a memory DC in response to WM_PAINT. So you can use GetDC() on WM_LBUTTONDOWN, but save the dc until WM_LBUTTONUP. Then log what you have drawn to redraw it in WM_PAINT.

                        – Michael Chourdakis
                        Mar 24 at 11:09

















                      so can i declare DC outside switch statement? can i just use WM_PAINT instead of WM_MOUSEMOVE?

                      – Andrew
                      Mar 24 at 10:54





                      so can i declare DC outside switch statement? can i just use WM_PAINT instead of WM_MOUSEMOVE?

                      – Andrew
                      Mar 24 at 10:54













                      In generic Windows apps, drawing is done in response to WM_PAINT. Drawing does not persist. This means that if your window is minimized, the next maximize won't show what you have drawn previously. That's why you draw it when Windows requests it, that is, in WM_PAINT. When doing real time drawing, you can use GetDC() to get the DC, but also you save what you have drawn (in your case, the start/end xy), and repeat it with a memory DC in response to WM_PAINT. So you can use GetDC() on WM_LBUTTONDOWN, but save the dc until WM_LBUTTONUP. Then log what you have drawn to redraw it in WM_PAINT.

                      – Michael Chourdakis
                      Mar 24 at 11:09






                      In generic Windows apps, drawing is done in response to WM_PAINT. Drawing does not persist. This means that if your window is minimized, the next maximize won't show what you have drawn previously. That's why you draw it when Windows requests it, that is, in WM_PAINT. When doing real time drawing, you can use GetDC() to get the DC, but also you save what you have drawn (in your case, the start/end xy), and repeat it with a memory DC in response to WM_PAINT. So you can use GetDC() on WM_LBUTTONDOWN, but save the dc until WM_LBUTTONUP. Then log what you have drawn to redraw it in WM_PAINT.

                      – Michael Chourdakis
                      Mar 24 at 11:09


















                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55322969%2fdraw-line-doesnt-work-what-might-be-the-problem%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                      Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                      Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript