1 / 24

建立 不規則形狀 的視窗

建立 不規則形狀 的視窗. 井民全製作. SetWindowRgn API. 利用 SetWindowRgn 我們可以指定視窗的輪廓. // 建立橢圓形狀的視窗範例 HRGN rgn; rgn = CreateEllipticRgn(0,0,200,100); // 建立橢圓 region SetWindowRgn (rgn,TRUE); // 設定目前視窗的外型. 當呼叫後 , 是否要重畫視窗. 指定輪廓. 橢圓視窗 – 以 Dialog 為例.

cedric
Télécharger la présentation

建立 不規則形狀 的視窗

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 建立不規則形狀的視窗 井民全製作

  2. SetWindowRgn API • 利用 SetWindowRgn我們可以指定視窗的輪廓 // 建立橢圓形狀的視窗範例 HRGN rgn; rgn = CreateEllipticRgn(0,0,200,100); // 建立橢圓 region SetWindowRgn(rgn,TRUE); // 設定目前視窗的外型 當呼叫後,是否要重畫視窗 指定輪廓

  3. 橢圓視窗 –以 Dialog 為例 BOOL CTriangleDemo2Dlg::OnInitDialog() { CDialog::OnInitDialog(); // 建立橢圓形狀的視窗 HRGN rgn; rgn = CreateEllipticRgn(0,0,200,100); // 建立橢圓 region SetWindowRgn(rgn,TRUE); // 設定目前視窗的外型 return TRUE; } 在 InitDialog 中加入 void CTriangleDemo2Dlg::OnPaint() { //重新畫元件 CDialog::OnPaint(); }

  4. 不規則形狀視窗通常都不會有 Title 所以,當你要移動視窗時,就必須要有特殊的處理 • 請你練習一下

  5. 加入滑鼠 Drag的功能 • Mouse Event Handle 自動產生對應的function 骨架 1. 選擇 Messages 2 void CTriangleDemo2Dlg::OnLButtonDown(UINT nFlags, CPoint point) { // 處理滑鼠左鍵按下的程式 }

  6. 自行加入滑鼠事件-- OnLButtonDown // [滑鼠功能] 當滑鼠左鍵按下時 void CTriangleDemo2Dlg::OnLButtonDown(UINT nFlags, CPoint point) { if ( !(m_dwFlags & DRAGGING) ) { // 若目前不是 dragging 狀態 m_pntMouse = point; m_dwFlags |= DRAGGING; // 設定目前為 Drag SetCapture();// 設定接收滑鼠輸入 } CDialog::OnLButtonDown(nFlags, point); }

  7. 自行加入滑鼠事件-- OnLButtonUp //[滑鼠功能] 當滑鼠左鍵彈起時 void CTriangleDemo2Dlg::OnLButtonUp(UINT nFlags, CPoint point) { if ( m_dwFlags & DRAGGING ) { // 若目前是 dragging 狀態 m_dwFlags &= ~DRAGGING; ReleaseCapture();// release 滑鼠輸入 } CDialog::OnLButtonUp(nFlags, point); }

  8. 自行加入滑鼠事件-- OnMouseMove // [滑鼠功能] 當滑鼠移動時, 移動視窗的位置 void CTriangleDemo2Dlg::OnMouseMove(UINT nFlags, CPoint point) { if ( m_dwFlags & DRAGGING ) { // 若目前是 Dragging 狀態,且滑鼠正在移動 RECT rect; GetWindowRect( &rect ); // 取出視窗位置 // 設定視窗的新位置 rect.left += point.x - m_pntMouse.x; rect.top += point.y - m_pntMouse.y; SetWindowPos( NULL, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE ); } CDialog::OnMouseMove(nFlags, point); } 計算偏移量 指定視窗位置與寬高 設定目前視窗的 z-order (目前 ignore)

  9. 練習 HRGN rgn; INT num[1]; POINT points[10]; num[0]=10; points[0].x = 304; points[0].y = 24; points[1].x = 232; points[1].y = 160; points[2].x = 64; points[2].y = 160; points[3].x = 192; points[3].y = 264; points[4].x = 136; points[4].y = 392; points[5].x = 304; points[5].y = 336; points[6].x = 456; points[6].y = 392; points[7].x = 424; points[7].y = 264; points[8].x = 552; points[8].y = 160; points[9].x = 384; points[9].y = 160; rgn = CreatePolyPolygonRgn( points, num, 1, WINDING ); SetWindowRgn(rgn, true); • 請建立星星形狀的視窗 參考程式碼

  10. 以BITMAP圖案為輪廓 • 重點是讀取影像mask, 產生 Region 描述 紅色為背景 Mask 影像 建構出來的視窗形狀

  11. 指定目前的 instance 圖檔 使用實際的寬高 指定圖檔型態 以BITMAP圖案為輪廓 // ==================== 建立形狀 ===================== // Step 1: 載入影像 HBITMAP hBmp = (HBITMAP) LoadImage( AfxGetInstanceHandle(), "Rgn.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if ( hBmp == NULL ) return TRUE; // Step 2:建立一個 Region, 令紅色為透明色 (transparent) HRGN hRgn = CreateRgnFromFile( hBmp, RGB(255,0,0) ); // Step 3:設定視窗大小與影像大小相同 SetWindowPos( NULL, 0, 0, m_dwWidth, m_dwHeight, SWP_NOZORDER | SWP_NOMOVE ); // Step 4:設定視窗的形狀 SetWindowRgn( hRgn, TRUE ); // ==================== End =====================

  12. CreateRgnFromFile • 這個部分需要大量的BMP 檔的相關知識 • 請直接參考 SOURCE CODE

  13. 為你的視窗加上背景

  14. 視窗繪圖原理概念Device Context • 當你想要在 window client area 畫圖或印出資料  你要透過 DC (Device Context) 即將輸出的資料 泛指任意輸出裝置 (螢幕,印表機)或檔案 DC 應用程式 GDI (圖形裝置介面 API) DC

  15. MFC的 CDC 類別 內容 m_hDC: 對應到目前的輸出 Device m_AttributeDC:讀取 DC 屬性用 CDC 衍生四種子類別 CDC CClientDC CWindowDC CPaintDC CMetaFileDC 回應 WM_Paint Message (即 OnDraw 傳進來 的參數) 對應到視窗 Client area 對應到整個 視窗(Frame 與 control) 對應到特殊檔案 (向量格式檔案)

  16. SelectObject function • 我們可以為裝置指定物件 • Brush  填滿的形式 • Pen  外框部分(視窗) • Bitmap • Font • Rgn • Palette (調色盤)

  17. 建立一個對應於目前工作區域的DC // Step 4: 加上背景 CDC* dc = GetDC(); // 取得目前 client area 的 DC m_dcBkGrnd = CreateCompatibleDC( dc->m_hDC ); // 建立一個memory DC ReleaseDC( dc ); // 使用完後,必須 release 該 DC // 指定一張影像到背景DC SelectObject( m_dcBkGrnd, hBmp );

  18. // ==================== 建立形狀 ===================== // Step 1: 載入影像 HBITMAP hBmp = (HBITMAP)LoadImage( AfxGetInstanceHandle(), "Rgn.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if ( hBmp == NULL ) return TRUE; // Step 2:建立一個 Region, 令紅色為透明色 (transparent) HRGN hRgn = CreateRgnFromFile( hBmp, RGB(255,0,0) ); // Step 3:設定視窗大小與影像大小相同 SetWindowPos( NULL, 0, 0, m_dwWidth, m_dwHeight, SWP_NOZORDER | SWP_NOMOVE ); // Step 5:設定視窗的形狀 SetWindowRgn( hRgn, TRUE ); // ==================== End ===================== 為視窗指定背景的部分 // Step 4: 加上背景 CDC* dc = GetDC(); // 取得目前 client area 的 DC m_dcBkGrnd = CreateCompatibleDC( dc->m_hDC ); // 建立一個memory DC ReleaseDC( dc ); // 使用完後,必須 release 該 DC // 指定一張影像到背景DC SelectObject( m_dcBkGrnd, hBmp );

  19. 畫上背景 void CTriangleDemo2Dlg::OnPaint() { // 取得目前視窗 client 區的 DC CPaintDC dc(this); // device context for painting // 在目前視窗上,畫上背景 if ( m_dcBkGrnd ) BitBlt( dc.m_hDC, 0, 0, m_dwWidth, m_dwHeight, m_dcBkGrnd, 0, 0, SRCCOPY ); }

  20. Window Property 應該選擇沒有 border • 否則會造成 無法對準的情況

  21. Appendix: BCB 的部分 #include <winuser.h>//Is user for SetWindowRgn()#include <wingdi.h>//Is user for CreatePolygonRgn() void __fastcall FormName::FormCreate(TObject *Sender){ HRGN Region; POINT Points[4]; //Define the points accross down Points[0] = Point(100 , 30 ); Points[1] = Point(200 , 200 ); Points[2] = Point(0 , 200 ); Points[3] = Point(105 , 30 ); //Define the region Region = CreatePolygonRgn(Points, 4, ALTERNATE); //Set the window to have the above defined regionSetWindowRgn(Handle, Region , True);} • 其中包含 • VB example • Delphi example 這個部分的程式碼來源:http://ftp.newave.net.au/~akia/rgn.htm#C%20Example

  22. 參考資料 • http://visualcpp.net/index.php?qID=31 • 精通視窗程式設計, 位元文化工作室 P.P.12-4

  23. 附錄: • 如果你把 #include “stdafx.h”拿掉時, 通常會出現 • “fatal error C1010: 尋找先行編譯標頭檔指示詞時找到未預期的檔案結尾“ 等錯誤訊息. • 你可以把 precompiled Header 取消

More Related