• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            作者:pengkuny
            下決心把MFC學好,
            從暑假到現(xiàn)在,
            連皮毛都沒學到一點,
            真他*丟臉.

            發(fā)現(xiàn)寫日記的方法效果不錯,
            該記住的終于記住了

            看了仍然不懂的,用"@#$%"符號表示.

            錯誤理解必然一大堆,只能期望日后補救拉,只是希望不要錯得太離譜.

            2006.11.10

            一.消息響應事件的模式,那么消息怎么起作用的?
            ?? 消息以調用一個窗口的窗口過程的形式來表明自己的存在.伴隨4個參數(shù):
            消息所指窗口句柄(包含很多窗口的信息),
            消息ID(整型值,消息類型,以WM_開頭),
            兩個名為wParam和lParam的32位參數(shù).

            .@#$%
            API函數(shù)RegisterClass注冊的類為WNDCLASS
            而"窗口類"指從MFC的CWnd派生的C++類

            三.匈牙利命名法:
            b,c/ch,By,clr,(x,y),(cx,cy),w,dw,n,I,l,s,sz/str,p,fn,h,wnd,MSG,WM_,g,AFXAPI,WINAPI,SW_,WS_,MM_
            函數(shù)名不使用下劃線
            所有的類型和常量都是大寫字母,但名字中可以允許有下劃線
            所有C++的類必須以大寫C為前綴,類名字的每一個子名的第一個字母都必須大寫

            四.熟悉一些常用的AFX函數(shù)

            五.接觸到的一些類:
            CCmdTarget--CWinTread--CWinApp
            Cwnd--CFrameWnd,凡是以Wnd結尾的類都是Cwnd類,框架窗口類


            六.protected:對外相當于pravite,對內相當于public

            七.頭文件AfxWin.h,里面包含所有類的聲明,可以仔細看一看

            八.查看CWinApp的類定義
            待查:分析CWinApp類;
            ???? DECLARE_DYNAMIC;

            ?

            2006.11.11

            一.應用程序窗口必須由InitInstance創(chuàng)建,故即使最小的MFC程序都必須覆蓋這個虛函數(shù).
            ?? 同理,CMainWnd繼承自CFrameWnd,它必須有自己的構造函數(shù),調用Create創(chuàng)建一個窗口.
            ?? CWinApp的一個非常重要的成員函數(shù)CWnd* m_pMainWnd;它是public的,指向CWnd類

            二@#$%
            protected:friend class CWinApp;WinApp是CFrameWnd的友元

            三.ShowWindow(m_nCmdShow);UpdateWindow();
            ?? m_nCmdWindow表示窗口CWnd的顯示狀態(tài),CWinApp的public成員函數(shù),其值以SW_前綴,默認為SW_SHOWNORMAL

            四.從Winmain.cpp中可以看到:
            ?? AfxWinMain在幕后操縱這一切的運行

            五.現(xiàn)在可以把框架窗口看作頂層窗口看待,它是應用程序與外部世界的主要接口.

            六.消息映射:將消息和成員函數(shù)相互關聯(lián)的表.
            BEGIN_MESSAGE_MAP (CMainWindow, CFrameWnd)
            ??? ON_WM_PAINT ()
            END_MESSAGE_MAP ()

            CMainWindow為消息所屬的類; CFrameWnd為消息所屬的類的基類,因為消息可以繼承.
            使用ON_MESSAGE(WM_SETTEXT,OnSetText);創(chuàng)建自己的消息映射.

            ?

            2006.11.13

            主題:在窗口中繪圖

            一.GDI(Graphics Device Interface)圖形設備接口負責圖形輸出.
            ?? 具體由設備描述表(DC)來做.

            二.4類設備描述表類:
            CPaintDC
            CClientDC
            CWindowDC
            CMetaFileDC

            二.創(chuàng)建一個設備描述表后,如CPaintDC dc(this);
            就可以調用各種畫圖函數(shù)了,dc.Fun();
            ?? 6個GDI對象:跟設備描述表dc是什么關系?
            基類:CGDIObject類
            畫筆Pen
            畫刷Brush
            字體Font
            位圖Bitmap
            調色板Palette
            區(qū)域Region
            ??
            ? 它們實際上刻畫了設備描述表dc的屬性,并不是dc的函數(shù),
            通過dc.SelectObject(GDI對象指針)選入設備描述表.

            三.回憶WM_PAINT消息是怎么產(chǎn)生的:
            移動了窗口
            原來遮掩的部分顯示出來
            窗口大小改變
            ?
            CPaintDC類只能干這個事,只能局限于響應WM_PAINT消息,所以要選用CClientDC類

            四.取得全屏訪問權,入屏幕截取程序,很少見
            傳遞NULL指針
            CClientDC dc(NULL);

            一般情況下,取this指針給構造函數(shù)即可:
            CPaintDC dc(this);
            CPaintDC *pDC = new CPaintDC(this);
            this指向調用對象本身,不可改變.
            ?

            五.掌握設備描述表屬性Attribute的常見術語
            文本顏色 CDC::SetTextColor
            背景顏色 CDC::SetBKColor
            背景模式 CDC::SetBKMode
            映射模式 CDC::SetMapMode
            繪圖模式 CDC::SetROP2
            分別由相關函數(shù)調用,非常方便.
            既然有Set函數(shù),毫無疑問,就有Get函數(shù)

            六.比如OnPaint函數(shù),每次調用完以后,函數(shù)內定義的設備描述表自然被銷毀
            想要保存它的狀態(tài),請使用
            CDC::SaveDC,對應就有:
            CDC::RestoreDC來恢復

            七.映射模式:
            一個邏輯單位對應的距離,畫圖的時候只要告訴GDI多少單位即可,
            實際上這些模式都擴大了本來的表示范圍,使得大尺寸的東東都可以壓縮比例顯示
            8種映射模式,非常簡單:
            (1)默認MM_TEXT
            (2)公制模式:y軸反轉,完全符合數(shù)學坐標,所以y值一定要用負的.
            (3)可編程模式:不反轉,但允許反轉
            ?? MM_ISOTROPIC? :x,y同等縮放
            ?? MM_ANISOTROPIC:x,y獨立縮放

            八.可編程模式
            SetViewportExt
            SetWindowExt


            九.補充:堆和棧的區(qū)別
            首先必須弄懂C/C++中內存區(qū)的分配:

            堆:順序隨意

            棧:先進后出

            一個由c/C++編譯的程序占用的內存分為以下幾個部分

            1、棧區(qū)(stack)— 編譯期間就分配好的內存空間,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結構中的棧。 一切管理由系統(tǒng)負責.

            2、堆區(qū)(heap) — 程序運行期間動態(tài)分配的內存空間,你可以根據(jù)程序的運行情況確定要分配的堆內存的大小.由alloca,new申請,并由free/delete釋放.注意它與數(shù)據(jù)結構中的堆是兩回事。

            3、全局區(qū)(靜態(tài)區(qū))(static)—,全局變量和靜態(tài)變量的存儲是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。 - 程序結束后有系統(tǒng)釋放
            static指函數(shù)調用后仍然不消失的局部變量.

            4、文字常量區(qū) —常量字符串就是放在這里的。 程序結束后由系統(tǒng)釋放

            5、程序代碼區(qū)—存放函數(shù)體的二進制代碼。

            棧:在Windows下,棧是由高地址向低地址擴展的數(shù)據(jù)結構,是一塊連續(xù)的內存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預先規(guī)定好的,在 WINDOWS下,棧的大小是2M,如果申請的空間超過棧的剩余空間時,將提示overflow。
            速度快.
            堆:堆是由底向高地址擴展的數(shù)據(jù)結構,是不連續(xù)的內存區(qū)域。
            容易產(chǎn)生碎片.


            舉例:
            ?CPoint ptX; 和 CPoint ptX = new CPoint();兩者的區(qū)別是什么?
            前者棧分配,后者堆分配,用完后delete.

            與C++不同,Java自動管理棧和堆,程序員不能直接地設置棧或堆。


            十.終于他媽的明白GetClientRect的作用了:
            CRect rect;
            GetClientRect(&rect);
            將當前窗口的尺寸(比如非最大非最小的狀態(tài))來初始化這個矩形,
            而不是用矩形來初始化窗口大小(難怪rect沒初始化)???????????????????????????????????????????????????????????????????????????????????????????????????????????

            十一.
            CRect rect;
            GetClientRect(&rect);
            dc.SetMapMode(MM_ANISOTROPIC);??????????????????? //可編程模式
            dc.SetWindowExt(500,600);???????????????????????? //邏輯尺寸就是500*600單位
            dc.SetViewportExt(rect.Width(),rect.Height());??? //設備單位/像素:rect.Width(),rect.Height()
            水平方向--每單位多少像素:rect.Width()/500
            垂直方向--每單位多少像素:rect.Height()/600????????????????????????????????????????????????????????? 縮放比例就這么來.

            SetWindowExt(x1, y1);?????????????????????
            SetViewportExt(x2, y2);

            SetWindowExt(100*x1, 100*y1);??????????????????????
            SetViewportExt(596*x2, 596*y2);
            效果完全一樣,無非是一個比例而已.

            在同比例縮放模式MM_ISOTROPIC下,
            縮放比例取min{x2/x1, y2/y1}!

            兩個范圍設置函數(shù)僅僅干了一件事,設置比例,其后畫圖使用邏輯單位,跟它們就沒有直接關系了.????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

            2006.11.15

            一.這句話不明白:
            "使用SetWindowExt和SetViewportExt時要注意:在MM_ISOTROPIC映射模式下,
            應該首先調用SetWindowExt.否則,部分客戶區(qū)可能會因落在窗口的邏輯范圍之外而不能使用。
            而在MM_ANISOTROPIC映射模式下,窗口范圍和視口范圍中先設置哪一個都無關緊要。"

            實際上,我實驗發(fā)現(xiàn):只要掌握放大因子k=min{x2/x1, y2/y1},和窗口真實邏輯大小(X,Y),那么畫出來的圖形(x,y)
            大小就是(kx,ky),只要kx<=X, ky<=Y,那么就不會有客戶區(qū)落在窗口的邏輯范圍之外的事情發(fā)生.

            二.坐標轉換
            CDC::LPtoDP
            CDC::DPtoLP

            三.移動原點,終于搞懂了
            SetViewportOrg(x,y)將視口原點移至(x,y)等價于通知Windows把邏輯點(0,0)映射成設備點(x,y),
            什么意思?就是把邏輯原點移到設備點(x,y)的位置,在這個新位置安家作為新的邏輯原點,
            對設備坐標沒有絲毫改變,所謂映射,只不過是一種簡單的移動關系,并不改變設備坐標
            同理,SetWindowOrg(x, y)將邏輯原點(x,y)移到原設備原點(0, 0)的位置

            述說的時候,(x, y)和(0, 0);邏輯點和設備點
            兩個"反義詞"不要同時反說,否則等于沒說.
            統(tǒng)一說:把邏輯點(*,*)移到設備點(*,*)的位置

            四.兩個設備坐標值:
            用戶坐標值
            屏幕坐標值
            互相轉化;
            CWnd::ClientToScreen
            CWnd::ScreenToClient

            四.獲取設備信息:
            CDC::GetDeviceCaps

            五.GDI畫筆CPen
            樣式PS_
            寬度
            顏色
            Windows自動選用當前畫筆給圖形加邊框,若選用PS_NULL"NULL筆",邊框就沒有了.

            擴展筆:@#$%

            六.GDI畫刷CBrush
            畫刷用來干什么?作為dc的屬性,它一旦選入,就自動填充一切畫出的封閉圖形
            類型:
            單色
            帶陰影線:6種,默認白色背景
            帶圖案:填充指定的位圖

            @#$%:
            移動畫刷原點:選入設備之前
            brush.UnrealizeObject();
            dc.SetBrushOrg(x0, y0);//注意,畫刷原點以設備坐標值給出
            dc.SelectObject(&brush);


            七.CDC文本函數(shù):
            @#$%
            DrawText
            TextOut等

            八.GDI字體CFont
            一個很好用的API函數(shù)::ZeroMemory(指針,內存大小)將一塊內存清零.
            LOGFONT為字體結構,如:
            LOGFONT lf;
            ::ZeroMemory(&lf, sizeof(lf));
            初始化lf;
            lf.lfEscapement和lf.Orientation指定文本旋轉角度的10倍值


            CRect::OffsetRect(x,y)設置一個矩形坐標偏移量.

            光柵字體:位圖保存,不適合縮放,MS Sans Serif
            TrueType字體:任意縮放
            Times New Roman
            Arial
            Courier
            Symbol

            八.備用對象:一種非常好的GDI對象,系統(tǒng)預定義,無須顯式創(chuàng)建,也無須刪除,非常安全.
            CDC::SelectStockObject選入DC
            CDC::CreateStockObject賦給已有對象

            九.怎么刪除GDI對象?
            堆上創(chuàng)建的/new,需要CGDIObject::DeleteObject顯式刪除

            十.怎么取消GDI對象?
            變相的方法:通過選入另外一個GDI對象將當前GDI對象從設備描述表中"提取"出來.
            先保存調用SelectObject時返回的指針,
            然后將這個指針重選默認對象,或者選入備用對象
            來取代當前對象.

            實際上,@#$%

            十一.CString::Format:
            與C語言的printf功能一樣,支持printf所有的格式,
            如string.(_T("d%"), i/100);
            然后dc.TextOut即可.

            十二.滾動條:窗口樣式參數(shù),將來學到更高級的滾動條控件,就應該可以拋棄這種低級的方式
            滾動條向它所屬的窗口發(fā)送消息,一切響應有窗口來做,滾動條很少自己響應消息.

            Create的第三個參數(shù)
            WS_VSCROLL , WS_

            設置:范圍,位置,頁面大小
            方法一:
            CWnd::SetScrollRange和CWnd::SetScrollPos

            參數(shù)TRUE意味著重不重畫,小技巧

            方法二:CWnd::SetScrollInfo,很好用,如:
            ??? SCROLLINFO si;
            ??? si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
            ??? si.nMin = 0;
            ??? si.nMax = nHScrollMax;
            ??? si.nPos = m_nHScrollPos;
            ??? si.nPage = m_nHPageSize;

            ??? SetScrollInfo (SB_HORZ, &si, TRUE);


            十三.滾動條滑塊大小與窗口尺寸同步變化:
            WM_SIZE消息:
            窗口建立的時候,就有WM_SIZE的消息傳來,以后只要窗口尺寸改變,就有WM_SIZE消息傳來
            用OnSize處理.
            afx_msg void Onsize(UINT nType, int cx, int cy);輕松解決//類型+新寬度+新高度


            十四.滾動條消息類型自動傳遞給nCode參數(shù),位置信息pos都是自動傳遞給消息處理函數(shù),不用擔心
            WM_HSCROLL,WM_VSCROLL不是具體的消息類型,SB_才是,
            OnHScroll,OnVScroll.

            但是在任何事件中,更新滾動條的位置都是程序員的事情,滾動條自己不會干.

            小技巧:比如有時忽略"拖動滾動條"消息SB_THUMBTRACK,
            ?????? 而只管"釋放滾動條"SB_THUMBPOSITION


            十五.ScrollWindow(x,y)://向右滾動x個像素,向下滾動y個像素
            數(shù)據(jù)快速拷貝滾動滾動,空出來的地方激活OnPaint去重畫



            待續(xù)……

            posted on 2006-11-15 13:56 哈哈 閱讀(2270) 評論(2)  編輯 收藏 引用

            評論:
            # re: 我的MFC學習筆記(Cont) 2006-12-19 21:37 | MOKEY
            支持博主  回復  更多評論
              
            # re: 我的MFC學習筆記(Cont) 2007-04-03 14:20 | phoenix
            我這學期才開始學MFC~~用GDI畫圖~以后有什么不懂的就問你哦  回復  更多評論
              
            久久综合九色综合久99| 久久精品国产免费| 四虎影视久久久免费观看| 日韩精品久久久久久久电影| 久久精品中文字幕一区| 国内精品伊人久久久久| 久久久久无码精品| 久久久亚洲欧洲日产国码aⅴ | 久久美女人爽女人爽| 狠狠精品久久久无码中文字幕| 日韩欧美亚洲综合久久| 久久精品国产91久久综合麻豆自制| 久久久久久青草大香综合精品| 亚洲综合伊人久久大杳蕉| 99热都是精品久久久久久| 中文字幕无码久久精品青草| 久久国产乱子精品免费女| 亚洲午夜久久久久妓女影院| 久久精品国产亚洲7777| 国产精品一久久香蕉产线看 | 精品国产一区二区三区久久久狼| 国产精品99久久久久久宅男| 久久亚洲精品人成综合网| 手机看片久久高清国产日韩| 久久国产精品一区二区| 少妇久久久久久久久久| 欧美精品乱码99久久蜜桃| 欧美国产精品久久高清| 久久一区二区免费播放| 久久久WWW成人| 91久久国产视频| 国产高清美女一级a毛片久久w| 91麻豆国产精品91久久久| 美女久久久久久| 一本色道久久88加勒比—综合| 欧美伊人久久大香线蕉综合| 亚洲国产二区三区久久| 精品乱码久久久久久久| 色欲av伊人久久大香线蕉影院| 天天躁日日躁狠狠久久| 区久久AAA片69亚洲|