• <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學好,
            從暑假到現在,
            連皮毛都沒學到一點,
            真他*丟臉.

            發現寫日記的方法效果不錯,
            該記住的終于記住了

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

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

            2006.11.10

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

            .@#$%
            API函數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_
            函數名不使用下劃線
            所有的類型和常量都是大寫字母,但名字中可以允許有下劃線
            所有C++的類必須以大寫C為前綴,類名字的每一個子名的第一個字母都必須大寫

            四.熟悉一些常用的AFX函數

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


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

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

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

            ?

            2006.11.11

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

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

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

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

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

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

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

            ?

            2006.11.13

            主題:在窗口中繪圖

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

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

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

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

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

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

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

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

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

            八.可編程模式
            SetViewportExt
            SetWindowExt


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

            堆:順序隨意

            棧:先進后出

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

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

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

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

            4、文字常量區 —常量字符串就是放在這里的。 程序結束后由系統釋放

            5、程序代碼區—存放函數體的二進制代碼。

            棧:在Windows下,棧是由高地址向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M,如果申請的空間超過棧的剩余空間時,將提示overflow。
            速度快.
            堆:堆是由底向高地址擴展的數據結構,是不連續的內存區域。
            容易產生碎片.


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

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


            十.終于他媽的明白GetClientRect的作用了:
            CRect rect;
            GetClientRect(&rect);
            將當前窗口的尺寸(比如非最大非最小的狀態)來初始化這個矩形,
            而不是用矩形來初始化窗口大小(難怪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}!

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

            2006.11.15

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

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

            二.坐標轉換
            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);邏輯點和設備點
            兩個"反義詞"不要同時反說,否則等于沒說.
            統一說:把邏輯點(*,*)移到設備點(*,*)的位置

            四.兩個設備坐標值:
            用戶坐標值
            屏幕坐標值
            互相轉化;
            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文本函數:
            @#$%
            DrawText
            TextOut等

            八.GDI字體CFont
            一個很好用的API函數::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對象,系統預定義,無須顯式創建,也無須刪除,非常安全.
            CDC::SelectStockObject選入DC
            CDC::CreateStockObject賦給已有對象

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

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

            實際上,@#$%

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

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

            Create的第三個參數
            WS_VSCROLL , WS_

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

            參數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參數,位置信息pos都是自動傳遞給消息處理函數,不用擔心
            WM_HSCROLL,WM_VSCROLL不是具體的消息類型,SB_才是,
            OnHScroll,OnVScroll.

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

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


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



            待續……

            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畫圖~以后有什么不懂的就問你哦  回復  更多評論
              
            午夜精品久久影院蜜桃| 精品久久久久久久| 国产ww久久久久久久久久| 麻豆一区二区99久久久久| 日韩中文久久| 久久亚洲精品国产亚洲老地址| 国产精品热久久无码av| 国产精品99久久不卡| 久久99精品国产99久久6| 国产精品久久久久一区二区三区| 婷婷久久综合九色综合98| 精品久久一区二区| 久久99精品久久久久久9蜜桃| 久久影视国产亚洲| 波多野结衣久久| 久久精品亚洲日本波多野结衣 | 久久久久久久97| 7777久久久国产精品消防器材| 99久久精品免费看国产一区二区三区| 亚洲精品午夜国产VA久久成人| 久久亚洲精品无码AV红樱桃| 66精品综合久久久久久久| 亚洲精品tv久久久久久久久久| 久久99精品久久久大学生| 99国产欧美精品久久久蜜芽| 99久久人人爽亚洲精品美女| 久久91精品国产91久| 国产麻豆精品久久一二三| 久久久精品国产亚洲成人满18免费网站| 最新久久免费视频| 久久国产一区二区| 久久久久亚洲av成人网人人软件| 99国产欧美久久久精品蜜芽| 久久伊人精品青青草原日本| 91精品国产高清久久久久久io | 久久精品国产一区二区| 亚洲午夜无码久久久久小说| 久久777国产线看观看精品| 久久久这里只有精品加勒比| 91超碰碰碰碰久久久久久综合| 97久久婷婷五月综合色d啪蜜芽 |