我想上一篇提到了畫一條線,那麼今天就繼續聊聊繪線的函數吧。

 

本來接著是想畫一個圓,可是找來找去就是找不到畫圓的函數,只有畫橢圓的函數,
好吧,就來變通一下下。

 

畫橢圓的函數:
Ellipse(HDC hdc, int nLeftRect, int nTopRect, int RightRect, int nBottomRect)
只要我們把這個矩形參數設成正方形,那麼他所畫出來的橢圓形就變成圓形了,哇!太好了。
當然啦,把這矩形參數設成長方形的時候,畫出來的就是橢圓形了。

 

看似達到我想要的目的了,可是當我再畫一直線進入到這圓形的內部時卻產生畫面閃爍的問題,
同樣的,畫兩個圓有交集的部份也一樣會發生閃爍的問題,這…可就不是我想要的答案。

 

為了證實我的想法,再來一個矩形的函數試試吧!

 

畫矩形的函數:
Rectangle(HDC hdc, int nLeftRect, int nTopRect, int RightRect, int nBottomRect)

 

鏘鏘~
結果和畫橢圓形的時候一樣。雖然我並不知道其內部的處理方式為如何,但…或許是畫封閉式的圖形
都會有這個情形吧。如果我的假設推斷是正確的,那……只能找畫非封閉圖形函數了。

 

(((我要一個圓啦)))

 

那就畫弧線的函數吧!也許畫兩個半圓的弧線就可以湊成一個圓了,聰明吧~【挑眉】
再想想,何不試試把起點當成終點,看看會是怎樣的結果,反正試又不用錢。

 

弧線的函數:
Arc(HDC hdc, int nLeftRect, int nTopRect, int RightRect, int nBottomRect,
int nXStartArc, int nYStartArc, int nXEndArc, nYEndArc)
只要把nXEndArc﹦nXStartArc,nYEndArc﹦nYStartArc,賓果!!!

 

因為畫了一條線,就想要畫一個圓。為了要畫一個圓,測試了橢圓、矩形、弧線函數,
當然也讓大腦燃燒了一下下,對於自學者的我來說,好玩。

 

沒動到resource.rc,就不重貼resource.rc了。

 


➻➼➸➳➺➻➴➵➶▶♕♖♗♘♙♚♛ 我是可愛的分隔線  ➻➼➸➳➺➻➴➵➶▶♕♖♗♘♙♚♛


main.cpp


#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define IDM_Demo1      1001    
#define IDM_Line       1002


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
char szAppName[] = "HelloWin";
HWND hwnd ;
MSG msg ;
WNDCLASSEX wndclass ;
wndclass.cbSize = sizeof(WNDCLASSEX) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wndclass.lpszMenuName = "DODO";  
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = 0 ;

RegisterClassEx (&wndclass);


hwnd = CreateWindowEx (
0,
szAppName,

"Graph 繪製圖形",  //  純好玩.. 改一下
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL) ;


ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}


return msg.wParam ;
}


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

switch (message)
{
HDC hdc;
 
case WM_PAINT:
     hdc = GetDC(hwnd);
     MoveToEx(hdc,80,80,NULL);
    
 LineTo(hdc,180,80);   //  重疊部份就會閃爍
    
  
 ///// 增加這段程式碼 ↓↓↓↓↓↓↓
    
     Ellipse (hdc,100,100,200,200);
     Ellipse (hdc,250,200,350,250);  // 沒重疊到就不會閃爍
     Arc (hdc,260,260,300,300,120,60,120,60);
     Rectangle(hdc,10,10,150,150);

     
    
/////  增加這段程式碼 ↑↑↑↑↑↑↑
    ReleaseDC(hwnd,hdc);
    return 0;

case WM_CREATE:
     return 0 ;
    
case WM_COMMAND:                        
        switch(LOWORD(wParam))
    {
            case IDM_Demo1:
                 
              break;
            
             case IDM_Line:
                 {   hdc = GetDC(hwnd);
                     MoveToEx(hdc,20,20,NULL);
                     LineTo(hdc,150,20);
                     ReleaseDC(hwnd,hdc);
                 }  
                break;
      }
       
       return 0 ;

case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}


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

 

➻➼➸➳➺➻➴➵➶▶♕♖♗♘♙♚♛ 我是可愛的分隔線  ➻➼➸➳➺➻➴➵➶▶♕♖♗♘♙♚♛

 

2020-12-26 補記

 

經過幾天的思考,想想或許還有些什麼吧。
再小小修改了一下程碼,居然有不同的結果,我們一起來瞧瞧。


case WM_PAINT:
//      hdc = GetDC(hwnd);
        hdc = BeginPaint(hwnd,&ps);      // 若改用這樣則不會閃爍 //*

        MoveToEx(hdc,80,80,NULL);
        LineTo(hdc,180,80);   //  重疊部份就會閃爍 
    
    ///// 增加這段程式碼 ↓↓↓↓↓↓↓
    
        Ellipse (hdc,100,100,200,200);  //  這是取正方形範圍來畫圓
        Ellipse (hdc,250,200,350,250);  // 沒重疊到就不會閃爍
        Arc (hdc,260,260,300,300,120,60,120,60);
        Rectangle(hdc,10,10,150,150);
    
    /////  增加這段程式碼 ↑↑↑↑↑↑↑

//      ReleaseDC(hwnd,hdc);
        EndPaint(hwnd,&ps);                // 若改用這樣則不會閃爍 //*

    return 0;


發覺Ellipse()和Rectangle()就是畫它所圈起來的整個範圍,不只是畫框框線條,
而Arc()和LineTo()就只是畫線條而已。

 

另一方面,hdc = GetDC(hwnd) 會自動的一直重繪,所以才會不斷的閃爍,
而 hdc = BeginPaint(hwnd,&ps),並不會一直的重繪,只有在改變視窗大小
的時候,才重繪一次,所以就不閃爍了,各位可以自行試試。

 

 

.

 

 

延伸閱讀

 

[伊蒙 dev c++] 視窗程式學習筆記

 

[做中學 dev c++] dev c++

 

 

 

 

 

 

arrow
arrow
    文章標籤
    Graphic 繪製圖形
    全站熱搜

    伊蒙‧普羅客 發表在 痞客邦 留言(2) 人氣()