Gribble1 - CWnd全屏播放
介紹 蛀木水蝨n。"呈現為不可讀文字的隨機二進位制資料。資料中的噪聲特徵 流顯示為gribble。位元率不匹配的調變解調器通常會產生gribble(更具體地說,波特率) 嘔吐)。將二進位制檔案轉儲到螢幕是一個很好的抱怨源,並且(如果鈴聲/揚聲器是活動的) 頭痛。”術語詞典 多年前,當我第一次開始玩“pooters mumble”時,其中一件“有趣”的事情就是玩 用一些簡單的圖形例程。通常,在圖形方面你做不了很多事情,但那就是 讓嘗試做一些事情變得更加有趣。 在開始使用Visual C和MFC後不久,有人讓我寫一個需要的程式 只是為了顯示一些圖形——僅此而已。實際上,我花了一段時間來弄清楚如何使用CWnd 所有伴隨的鈴聲和哨聲-框架,標題欄,等等。但你瞧,這並不難,而且 提供了一個整潔的畫布,可以使用任何您想要使用的東西。 如果您正在考慮編寫一個“kiosk”型別的程式,我認為我在這裡提供的Gribble視窗是有用的 (我)。我還希望Gribble1專案可以成為那些希望進行探索的人的一個有用的學習工具 Windows圖形的世界,所以我寫這篇文章主要是作為初學者的教程。那就是說,我不太會去 在這篇短文中深入探討裝置上下文和GDI物件的主題——這裡的目標只是得到 Gribble視窗啟動並執行,並提供一個簡單的示例(經典的“Lissajou”圖)來啟動。 Gribble1專案 Gribble1是一個現成的VC6應用嚮導生成的基於MFC的EXE專案,不支援文件/檢視。與 這樣,我就添加了一個名為Gribble的選單項,在CGribble1App中處理了Go選項。 接下來,我使用類嚮導建立了一個CGribbleWnd類——選擇新類,然後派生CGribbleWnd 來自“通用的CWnd”。(你需要滾動螢幕才能看到這個。)然後我聲明瞭一個CGribbleWnd的例項 在App類中,並叫它m_wndGribble。 現在,CWnd在建立之前都不是視窗,在這裡您有機會定義一些非常基本的內容 屬性。這是我們在CGribbleWnd本身之外唯一需要的程式碼,如果你需要的話,你會使用它 在您自己的專案中合併CGribbleWnd。在我的例子中,Gribble視窗在CGribble1App::OnGribbleGo()中建立。 使用它自己的視窗類和WS_VISIBLE|WS_POPUP的最小屬性集。這是最小的 屬性設定,去掉那些討厭的邊框和東西。 我們在這裡要做的就是註冊視窗類並呼叫m_wndgribb . createex()—內建的 CWnd方法: 隱藏,複製Code
void CGribble1App::OnGribbleGo() { // Let's create the Gribble window! if(!m_wndGribble.m_hWnd) { CString csWndClass = AfxRegisterWndClass(CS_OWNDC, 0, 0, 0); if(!(m_wndGribble.CreateEx(WS_EX_LEFT, (LPCTSTR)csWndClass, "Gribble Window", WS_VISIBLE|WS_POPUP, 0,0,0,0, NULL, NULL ))) { AfxMessageBox("Failed to Create Gribble Window)"); return; } } }
我們的Gribble視窗應該能夠從那裡獲取它,這是在它的OnCreate方法中做到的: 隱藏,收縮,複製Code
int CGribbleWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; // load nifty cursor m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR2); // we'll want to do this in OnActivate too SetCursor(m_hCursor); ShowCursor(true); // since this window has its own DC we can stash it away... m_pDC = GetDC(); // get some screen stats... m_pixelsX = m_pDC->GetDeviceCaps(HORZRES); m_pixelsY = m_pDC->GetDeviceCaps(VERTRES); m_bitsPixel = m_pDC->GetDeviceCaps(BITSPIXEL); TRACE("Screen is %d by %d\n", m_pixelsX, m_pixelsY); TRACE("Color depth is %d bits per pixel\n", m_bitsPixel); // full screen - in whatever color OnEraseBkgnd is using... MoveWindow(0,0,m_pixelsX, m_pixelsY); return 0; }
這裡,我們做一些準備。首先,我們需要裝置上下文,這樣我們就能知道螢幕的大小 是多少。我們可以用GetDeviceCaps()請求更多的資訊,但現在我們真正需要的是 所關心的是x和y的最大值。(獲取顏色深度的呼叫是從原始得到的 類,它需要檢查設定對於它正在使用的點陣圖是否足夠高。) 接下來的管理工作是通過呼叫MoveWindow()將視窗大小調整為螢幕大小。 (注意,當我們呼叫CreateEx()時,我們為頂部、左側、寬度和高度指定了0,因此我們需要 這樣做。) MoveWindow()方法有第五個引數bRepaint,預設值為TRUE和 開始滾動我們的球-告訴作業系統,我們想要排隊一些繪畫訊息。哪一個 反過來,結果是我們得到一些繪畫資訊。 到目前為止一切都很好——但是我們的泛型CWnd派生類需要處理這些繪製訊息,特別是WM_ERASEBKGND WM_PAINT,因為基類(CWnd)沒有為我們做任何事。類嚮導的救援 再次—選擇CGribbleWnd,突出顯示WM_ERASEBKGND條目並選擇Add Function,然後 編輯程式碼。我的CGribbleWnd::OnEraseBkgnd()是這樣的: 隱藏,複製Code
BOOL CGribbleWnd::OnEraseBkgnd(CDC* pDC) { // we'll configure this later... m_backColor = RGB(0,0,0); CBrush cb(m_backColor); HBRUSH hOldBrush = (HBRUSH)pDC->SelectObject(cb); RECT rect = {0,0,m_pixelsX,m_pixelsY}; pDC->FillRect(&rect,&cb); pDC->SelectObject(hOldBrush); cb.DeleteObject(); return TRUE; }
這裡我們建立了一個筆刷,一種特殊型別的GDI物件,並使用它使螢幕變黑。這就 我們有一個大黑屏。 注意這裡有一個非常重要的程式碼三明治,如果您的程式要成為a,您必須遵守它 良好的Windows公民,即當一個GDI物件被選擇到一個關聯裝置時,舊的物件必須是 儲存和恢復。這允許裝置上下文在完成時正確地返回資源,並儲存您 資源洩露這一可怕的罪惡。當我們談到這個問題時,還有兩點- 1。建立視窗類 正如我上面提到的,擁有自己的關聯裝置也被認為是一個禁忌。我這樣做是為了(希望)儲存 時間,在呼叫GetDC的上下文中。2. 上面的程式碼三明治可以用c替換呼叫SaveDC () 和RestoreDC(),可以方便的很多物件時被選中的裝置上下文。 接下來,使用類嚮導建立OnPaint()方法中,我們得到了一個不錯的小練習 我們的windows圖形。我看起來像這樣: 隱藏,收縮,複製Code
void CGribbleWnd::OnPaint() { CPaintDC dc(this); // device context for painting /** Now do some drawing... how bout a Lissajou figure... { Asin(wt + B) } **/ // normally we'd do this kind of initialization in OnCreate or the constructor, // but I want to localize things here, so we can treat OnPaint as a mini program! // start with a classic seed for the Lissajou... one time init... static int s_nLisXCoef = 1; static int s_nLisYCoef = 3; static int s_nLisYOffset = 44; ++s_nLisXCoef; ++s_nLisYCoef; int x,y; for (float t = 0; t < 32767; t+=.2) { x = sin(s_nLisXCoef*t) * m_pixelsX/2 + m_pixelsX/2; y = sin(s_nLisYCoef*t+s_nLisYOffset) * m_pixelsY/2 + m_pixelsY/2; dc.SetPixel(x, y, RGB(255,80,255)); } // Do not call CWnd::OnPaint() for painting messages }
有程式碼CGribbleWnd: OnLButtonDown()呼叫()開始失效 整個繪畫過程,導致一個新的圖被顯示在響應滑鼠單擊。的 程式碼32767電話設定畫素,所以它不會很快回應你的滑鼠點選,但是 不太壞又是;隨著資料越來越複雜,其整潔看他們填寫。 可能唯一的另一件事是漂亮的遊標。有兩個遊標中定義的資源 編輯器和OnCreate載入,並使用第二個,一種StarCraft-like箭頭。保持這 游標需要處理最後一個訊息: 隱藏,複製Code
void CGribbleWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { CWnd::OnActivate(nState, pWndOther, bMinimized); if(nState != WA_INACTIVE ) { SetCursor(m_hCursor); ShowCursor(true); } }
最後一個新增處理程式沒有提到OnKeyDown,用於出口通過DestroyWindow () 當escape鍵被按下。 總結 現在你明白了吧,一個標準的CWnd有六個訊息處理程式新增(其中一些很簡單)和你 祝你有美好的全屏視窗圖形。顏色你可以玩,在離開之前 Lissajou主題開始你可能想嘗試不同的係數等。這裡唯一的圖形叫SetPixel (), 它不需要任何的GDI物件或SelectObject()呼叫,所以你可以安全地玩耍,沒有 消耗資源的恐懼。 Lissajou資料是一個典型的“簡單”圖形的東西。也許一些數學上的 介意我們中間有其他一些很酷的公式來分享。那太好了,我試圖使OnPaint () 或多或少獨立使用本地靜態var 類成員,如果你堅持這個會議你可以提交有趣的新蛀木水蝨概念 通過貼上OnPaint()程式碼到一個訊息併發布它。也許有人能夠發現 蛀木水蝨應該是什麼樣子。 蛀木水蝨快樂 本文轉載於:http://www.diyabc.com/frontweb/news5222.html