亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 編寫 windows 標準控件㈡ .txt

?? 會變語言實現的一些程序
?? TXT
?? 第 1 頁 / 共 3 頁
字號:
編寫 Windows 標準控件㈡ 
相關的例子:下載>>>  作者:AoGo 于2007-12-16上傳   

--------------------------------------------------------------------------------


    上一章我們編寫了一個簡單地平坦按鈕控件,最后留的習題,不知道大家有沒有試著去完成,其實是很簡單地,問題在于繪出右邊的小三角形的圖形,自己畫?用圖片?呵呵,都不用,用 API 函數吧:

    invoke DrawFrameControl,hdc,lpRT,DFC_SCROLL,DFCS_SCROLLDOWN 

    這個函數通過指定不同的標志性參數,來重繪按鈕,菜單,滾動條,窗口標題欄等不同的部位,比如上面函數就表示要重畫滾動條的向下滾動鍵頭的圖形。多試試不同的參數看看,你會發現很有意思的東西。
    學習編程,舉一反三是很重要的,可是讓你快速積累經驗,比如,在 MSDN 或者 API 手冊中,搜索上面這個函數時,會有相似的函數列出來,這個時候一定要依次稍稍看一下,不要求立即使用,但是腦子里有印象,下一次說不定就能用上。
    除了這個圖形,還有那個分隔線,用 DraEdge 吧:

    invoke SetRect,addr lpRT,top,left,bottom,left+2      ;寬度2個像素,可畫出分隔線
    invoke DrawEdge,hdc,lpRT,BDR_SUNKENOUTER,BF_RECT 

    原來本章是打算完成這個習題,然后封裝。并且,告訴大家在不動控件代碼的情況下,通過接管通知消息來擴展在為顏色選擇器的功能,文章都已經寫得差不多了,突然發現,我是要寫“編寫”的教程,而不是使用,而接管消息實現什么功能的,這已經脫離了這個范疇,所以,苦惱了幾天,還是下決心重寫。T_T 。。。

    在本章中,我們將編寫一個新的控件,這個控件和之前的相比,會復雜得多,它的重點在于告訴大家如何使用不可定的操作集,比較簡單的,就是列表控件了。

    同樣,例子已經寫好,代碼仍然很多,下載之后,使用 MASMPlus 打開它,先編譯一下吧。

    程序運行界面如下:

    正在處理工程文件...
    ml.exe /c /coff /Fo"List.obj" "D:\MASMPlus1.2\Project\ControlLIB\List.asm"
    ml.exe /c /coff /Fo"Control.obj" "D:\MASMPlus1.2\Project\ControlLIB\Control.asm"
    link.exe /LIB "list.obj" /OUT:"Control.LIB" "Control.obj"

    正在處理工程 ...
    ml.exe /c /coff /nologo /Fo"UseControl.obj" "D:\MASMPlus1.2\Project\ControlLIB\UseControl.ASM"
    link.exe /SUBSYSTEM:WINDOWS /nologo /OUT:"UseControl.exe" "UseControl.obj"

    準備就緒:D:\MASMPlus1.2\Project\ControlLIB\UseControl.exe


    

    看上面的編譯信息,你是否查覺到了什么呢?呵呵,從這一章開始,我們將使用建立LIB的方式來寫控件,前一章的FlatButton控件也包含在內,因為兩個控件都是單獨的OBJ鏈接成LIB的,所以,如果你只使用其中一個控件,只需要調用其相應的注冊函數就可以了,沒有注冊的控件調用,是不會包含到你的程序中的,這樣,當你的控件越來越多時,也只需引用一個庫,用多少個就插入多少個到程序中,簡單方便。這就是控件庫了。

    同時,不僅僅是控件,包含單獨的函數也是可以的,比如你寫了一個排序的函數,只需要按獨立的方式編寫并編譯,再全部一次鏈接,這樣這個函數也是一個模塊。

    有任何不明折的地方,單擊右鍵看一下參數設置吧。

    本章寫的控件,是 List,列表控件,按上一章的方式,我們來進行解說。

    首先,是確定 List 所需的結構:

 
   列表控件是一個多操作無素的控件,比如可以有不定個數的項目,每個項目文本不同,所以,我們需要使用內存來進行管理,我使用的方法是與索引對應的數組來保存每一個項目內存,當刪除時釋放對應的內存并移動數組,為什么不使用更好的內存管理呢?更好的結構同時也是更復雜的,這個時候就要按最初的想法來確定,如果每一個項目都要有狀態,比如多選,或者是為了適應更大量數據處理,就必須用鏈表或者別的方法,而我的最初設計,只是做一個純列表框控件,所以,這個時候使用直接的DWORD數組,反而會更好,因為它操作簡單,尋址方便。
   下面針對某些成員進行介紹。
   hHeap
   保存堆句柄,關于內存模式的選擇,我用的是堆內存,自己創建一個堆來使用,好處是,只需要釋放堆,內存就全部釋放了,不需要每個項目都去遍歷再釋放。當然大型數據處理時,就需要根據用戶的情況而定。這里我就不重復了,關于內存管理,如果細說幾乎可以寫本書了。
   fStyle
   保存控件的某些設置,MLFS_FOCUS表示控件是當前焦點,這樣不需要每次去GetFocus再判斷,這個標志在WM_SETFOCUS/WM_KILLFOCUS中被添加或刪除,MLFS_SHARED標識當前的圖像列表是否是用戶設置的,比如用戶手動設置了圖像列表,這樣我們不會在控件銷毀時去刪除它。
   iMaxWidth
   水平最大寬度,每添加一個項目,會自動獲得字符串的長度對比后保存最長的,用于設置水平滾動條
   iHeight
   項目高度,所有項目的高度都是相同的。當翻頁,上下,刷新等操作時,需要高度進行計算。
   rt
   客戶區域,在WM_SIZE消息中保存,因為大小的變化是一定會有WM_SIZE消息的,保存后在其它消息中使用時,不需每次都使用GetClientRect來得到。 

    lpItems是一個指向 DWORD 的數組,用于保存每一個項目內存的地址,而列表框項目的索引與數組的索引是一樣的,所以操作與尋址都是很方便的,而指向的項目的結構,則是這樣:

 

    本控件的窗口風格比較少:



MLS_HASBITMAP        equ 1h          ;顯示圖像
MLS_OWNERDRAW        equ 8h          ;由父級重繪
MLS_CLASS            equ 20h         ;需要所有按鍵,默認只處理方向鍵,其它交給對話框處理(如果是在對話框中)
我們不再使用 WM_COMMAND 通知碼了,只使用通知消息,也即是WM_NOTIFY,事實上,只有簡單地控件,才會不使用 WM_NOTIFY 而使用 WM_COMMAND。
 

    消息的文檔我就不再細述了,單單對文檔來解說,是沒有效果的,參照代碼來看,首先是函數:

注冊控件函數 RegisterMyList

 
注冊列表控件的函數,wc.style不再使用 CS_PARENTDC,并且需要雙擊。 

發送通知消息函數 ParentNotify

 
向父窗口發送通知消息,與上一章不同的時,列表控件發送通知消息時,使用的是自己的結構:



前面的 hdr 是原本的 NMHDR 結構,這是固定的,后面是一個枚舉結構體,其實都是表示一個成員,只是在使用時用于區分是哪個通知消息。
;通知消息要小于NM_LAST,大于NM_LAST的是系統使用的。注意系統通知消息為負數,所以這里是減而不是加


NMN_SELCHANGING    equ NM_LAST-1             ;選擇更改中,返回非零值取消選擇更改,iCurrPos=要選擇的項目
MLN_SELCHANGED     equ NM_LAST-2             ;選擇更改的,iOldSel=指向舊的選擇索引
MLN_CLICK          equ NM_CLICK              ;項目單擊,XY=當前坐標,可以取消
MLN_SETFOCUS       equ NM_SETFOCUS           ;設置焦點,hWndFocus=失去焦點的窗口句柄
MLN_KILLFOCUS      equ NM_KILLFOCUS          ;失去焦點.hWndFocus=得到焦點的窗口句柄
MLN_DBLCLK         equ NM_DBLCLK             ;雙擊,iPos=當前選擇
MLN_IMAGECHANGED   equ NM_LAST-3             ;圖像列表更改了。hImageList=新的圖像列表

 

重繪項目函數 DrawItem

DrawItem    proc uses esi edi ebx,hDlg,hdc,lpMYLIST,Item_Index,lpRECT,WndStyle 
hDlg       列表控件句柄
hdc        設備上下文,這個參數如果沒0,函數將從hDlg獲得DC。
lpMYLIST   窗口結構地址
Item_Index 項目索引,為-1表示重繪的是空白部分
LPRECT     重繪區域
WNdStyle   窗口風格,將從這里判斷是否包含父組重繪風格。
這個函數是公用也是唯一的重繪項目函數,自動判斷是重繪還是通知父級。
 

 

消息處理



 

 

 

 

WM_CREATE        窗口創建

        invoke LocalAlloc,LMEM_ZEROINIT or LMEM_FIXED,sizeof MYLIST
        test eax,eax
        jnz @@SkipFail
            @@:         ;內存不足,直接返回-1,窗口創建失敗
            dec eax
            jmp @@Ret
        @@SkipFail:
        mov ebx,eax
        invoke SetWindowLong,hList,0,ebx     ;保存到實例的窗口字中
        mov [ebx].iHeight,MIN_HEIGHT
        invoke ImageList_Create,ICON_SIZE,ICON_SIZE,ILC_COLOR32 or ILC_MASK,0,0
        mov [ebx].hImage,eax
        invoke SendMessage,hList,MLM_RESTORE,0,0 
創建內存并保存,設置小最高度,創建圖像列表,然后初始化。 


WM_SIZE             窗口大小變化

        invoke GetClientRect,hList,addr [ebx].rt
        
        mov sci.fMask,SIF_RANGE or SIF_PAGE or SIF_DISABLENOSCROLL
        mov eax,[ebx].rt.bottom
        xor edx,edx
        div [ebx].iHeight
        mov ecx,[ebx].iCount
        sub ecx,eax
        .if [ebx].iTop>ecx             ;自動設置正確位置
            mov [ebx].iTop,ecx
            mov sci.nPos,ecx
            or sci.fMask,SIF_POS
        .endif
        
        mov sci.cbSize,sizeof SCROLLINFO
        mov sci.nPage,eax         ;設置滾動條一頁的范圍
        mov eax,[ebx].iCount
        dec eax
        mov sci.nMax,eax
        xor eax,eax
        mov sci.nMin,eax
        invoke SetScrollInfo,hList,SB_VERT,addr sci,TRUE
        
        mov sci.fMask,SIF_RANGE or SIF_PAGE or SIF_DISABLENOSCROLL
        mov eax,[ebx].iMaxWidth
        mov sci.nMax,eax
        mov eax,[ebx].rt.right
        mov sci.nPage,eax
        xor eax,eax
        mov sci.nMin,eax
        invoke SetScrollInfo,hList,SB_HORZ,addr sci,TRUE
        
        invoke InvalidateRect,hList,0,0 
保存窗口客戶區域,然后將高度和項目高做除法計算出一頁顯示的項目數。設置到滾動條上。消息滾動條總是使用iMaxWidth來設置。
然后刷新整個客戶區域,因為我們的控件并沒有包含大小變化時刷新的類標志。 


WM_PAINT        ;界面重繪

        invoke BeginPaint,hList,addr ps
        mov eax,[ebx].rt.top
        mov p.y,eax
        mov edi,[ebx].iTop
        @@:
        cmp edi,[ebx].iCount
        jae @F
            mov eax,[ebx].iHeight
            add eax,p.y
            invoke SetRect,addr ItemRt,[ebx].rt.left,p.y,[ebx].rt.right,eax
            invoke DrawItem,hList,ps.hdc,ebx,edi,addr ItemRt,fStyle
            inc edi
            mov eax,ItemRt.bottom
            mov p.y,eax
            cmp eax,[ebx].rt.bottom         ;比較項目是否已經在底部
            jb @B
        @@:
        
        ;如果項目不足一頁,使用默認畫刷畫出下面的部分
        mov eax,[ebx].rt.bottom
        .if p.y<eax
            invoke SetRect,addr ItemRt,[ebx].rt.left,p.y,[ebx].rt.right,[ebx].rt.bottom
            invoke DrawItem,hList,ps.hdc,ebx,-1,addr ItemRt,fStyle
        .endif
        invoke EndPaint,hList,addr ps 
從保存的iTop開始重繪,iTop是當前可見頁的第一項索引,設置區域之后,交給重繪函數。
當超過總數或者項目不足一頁,自動跳出,之后,判斷是否需要畫空白部分。同樣是交給重繪函數 



WM_LBUTTONDOWN             鼠標按下

        invoke ParentNotify,hList,MLN_CLICK,lParam
        .if eax==0
            mov eax,lParam
            shr eax,16
            xor edx,edx
            div [ebx].iHeight
            add eax,[ebx].iTop
            invoke SendMessage,hList,MLM_SETCURSEL,eax,MSC_SETFOCUS
        .endif 
首先發送消息給父窗口,如果返回0,表示繼續處理,計算當前點擊位置,然后再發送消息設置當前選擇項目。
這樣做是為什么呢?比如,用戶想做復選項目時,可以使用兩個圖形,設置dwData,然后在這里處理點擊并復選或者不選。呵呵。
 


WM_LBUTTONDBLCLK             雙擊

        invoke ParentNotify,hList,MLN_DBLCLK,[ebx].iSel 
并沒有特別的處理,但是發送通知消息給父窗口。讓父窗口處理 


WM_KEYDOWN                     ;鍵盤按下

        mov edi,[ebx].iTop
        mov ecx,[ebx].iSel
        mov eax,wParam
        .if eax==VK_UP
            .if sdword ptr ecx>0
                dec ecx
                invoke SendMessage,hList,MLM_SETCURSEL,ecx,MSC_SETVISIBLE
            .endif
        .elseif eax==VK_DOWN
            mov eax,[ebx].iCount
            dec eax
            .if ecx<eax
                inc ecx
                invoke SendMessage,hList,MLM_SETCURSEL,ecx,MSC_SETVISIBLE
            .endif 
上下鍵按下時,判斷是否在可移動區域,然后設置索引,調用MLM_SETCURSEL消息 
        .elseif eax==VK_PGUP
            mov eax,[ebx].rt.bottom
            xor edx,edx
            div [ebx].iHeight
            sub edi,eax
            .if sdword ptr edi<0
                xor edi,edi
            .endif
            sub ecx,eax
            .if SDWORD ptr ecx<0
                xor ecx,ecx
            .endif
            invoke SendMessage,hList,MLM_SETCURSEL,ecx,0
            mov [ebx].iTop,edi
            mov sci.nPos,edi
            call @@SetScrollPos
        .elseif eax==VK_PGDN
            mov eax,[ebx].rt.bottom
            xor edx,edx
            div [ebx].iHeight
            add ecx,eax
            mov edx,[ebx].iCount
            .if ecx>=edx
                mov ecx,edx
                dec ecx
            .endif
            add edi,eax
            mov edx,[ebx].iCount
            sub edx,eax
            .if edi>=edx
                mov edi,edx
                dec edi
            .endif

            invoke SendMessage,hList,MLM_SETCURSEL,ecx,0
            mov [ebx].iTop,edi
            mov sci.nPos,edi
            call @@SetScrollPos
        .endif 
向下/向上翻頁。思路是,翻頁是以iTop為準,向上時,如果位置是最頂或最底部了,則自動限制在范圍內。當前選擇與當前頂位置單獨設置可以在翻頁后,選擇項目位置坐標不變。 


WM_SETFOCUS        ;設置焦點

        invoke ParentNotify,hList,MLN_SETFOCUS,wParam
        or [ebx].fStyle , MLFS_FOCUS
        invoke InvalidateRect,hList,0,TRUE 
通知父窗口,然后加上MLFS_FOCUS風格。接著重繪 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲欧洲综合另类在线| 亚洲综合久久av| 久久婷婷综合激情| 欧美韩国日本一区| 亚洲福中文字幕伊人影院| 韩国中文字幕2020精品| 日本韩国一区二区三区| 欧美一区二区在线不卡| 日韩一区日韩二区| 久久97超碰国产精品超碰| 在线视频亚洲一区| 亚洲国产精品激情在线观看| 色婷婷av一区二区三区软件 | 亚洲在线一区二区三区| 91麻豆精品国产91久久久久久| 91小视频在线观看| 久久久久久久一区| 精品在线播放免费| 亚洲精品你懂的| 99久久精品国产观看| 欧美国产日韩精品免费观看| 欧美午夜影院一区| 亚洲va国产va欧美va观看| 色综合久久六月婷婷中文字幕| 中文子幕无线码一区tr| 精品美女在线播放| 九九视频精品免费| 亚洲电影在线播放| 亚洲欧洲三级电影| 日韩精品中文字幕一区 | 国产精品福利在线播放| av在线不卡电影| 国产精品理论在线观看| 欧美三级电影网站| 亚洲成人免费电影| 亚洲欧美日韩系列| 亚洲欧洲日韩一区二区三区| 国产亚洲精品福利| 一本一本久久a久久精品综合麻豆| 中文字幕视频一区二区三区久| 99久久精品免费看国产免费软件| 国产精品福利一区| 亚洲欧洲www| 欧美国产日韩一二三区| 精品国产百合女同互慰| 色婷婷国产精品综合在线观看| 亚洲码国产岛国毛片在线| 国产精品久久久久久久久久免费看| 成人精品免费看| 在线播放日韩导航| 激情小说欧美图片| 久久99这里只有精品| 亚洲激情图片一区| 亚洲精品高清在线观看| 亚洲一区二区三区四区中文字幕| 日韩美女一区二区三区四区| 精品少妇一区二区三区在线视频| 国产一区在线观看麻豆| 亚洲一区二区三区小说| 午夜精品视频在线观看| 国产精品第四页| 亚洲欧美精品午睡沙发| 亚洲精品videosex极品| 亚洲v日本v欧美v久久精品| 丝袜美腿亚洲一区| 亚洲免费观看在线视频| 亚洲第一狼人社区| 免费看日韩精品| 亚洲男同1069视频| 天天操天天干天天综合网| 蜜臀av一区二区在线免费观看 | 91麻豆免费看片| 日本乱人伦一区| 欧美电影一区二区| 日韩免费高清av| 中文字幕精品三区| 性欧美疯狂xxxxbbbb| 久久99国产精品免费网站| 国产电影一区在线| 韩国精品在线观看| 色综合天天狠狠| 日韩无一区二区| 日韩亚洲欧美综合| 久久九九99视频| 亚洲一区二区三区国产| 黄色日韩三级电影| 欧洲亚洲精品在线| 久久久久97国产精华液好用吗| 欧美一级在线视频| 亚洲免费三区一区二区| 国产在线精品免费| 在线免费观看一区| 国产欧美日韩在线| 国产精品国产三级国产有无不卡 | 国产欧美一区二区精品性色| 亚洲国产日韩精品| 国产在线观看免费一区| 一本久久综合亚洲鲁鲁五月天| 91视频xxxx| 国产欧美久久久精品影院| 丝袜亚洲另类欧美| 欧美日韩在线播放三区四区| 国产精品成人在线观看| 国内精品国产成人国产三级粉色| 日韩av在线免费观看不卡| 蜜桃视频在线观看一区二区| 成人黄色免费短视频| 精品奇米国产一区二区三区| 亚洲成人777| 欧洲精品在线观看| 亚洲免费在线视频| 波多野结衣中文字幕一区二区三区| 成人综合婷婷国产精品久久免费| 成人综合婷婷国产精品久久蜜臀 | 欧美在线不卡视频| 国产视频一区在线观看| 久久精品99国产国产精| 日韩欧美黄色影院| 视频在线观看国产精品| 欧美精品一卡二卡| 丝袜亚洲精品中文字幕一区| 欧美日韩一级片网站| 夜色激情一区二区| 国内不卡的二区三区中文字幕 | 欧美亚洲综合另类| 一区二区理论电影在线观看| 色久综合一二码| 中文字幕亚洲综合久久菠萝蜜| 性感美女久久精品| 欧美一区二区大片| 美女一区二区在线观看| 精品国产乱码久久久久久影片| 久久精品视频免费观看| 成人一二三区视频| 日韩伦理电影网| 国产精品性做久久久久久| 在线视频中文字幕一区二区| 亚洲成人av一区二区| 欧美一区二区三区影视| 国产一区二区调教| 国产精品无遮挡| 黄色成人免费在线| 国产精品沙发午睡系列990531| 亚洲国产精品久久久男人的天堂| 麻豆精品视频在线观看免费| 日韩精品一区二| 高清不卡一区二区| 日韩视频不卡中文| 国产成人丝袜美腿| 一区二区三区四区亚洲| 欧美精品三级日韩久久| 国产成人亚洲综合a∨猫咪| 国产精品欧美精品| 91精品免费在线观看| 国产成人av电影| 亚洲一二三四久久| 精品国产免费一区二区三区四区| 亚洲va在线va天堂| 久久在线观看免费| 99视频精品全部免费在线| 日韩在线一区二区| 国产精品久久久久久久岛一牛影视| 国产一区二区三区免费| 亚洲人成网站在线| 精品国产一二三区| 91黄色在线观看| 国产精品1024| 蜜臀久久99精品久久久久宅男 | 中文子幕无线码一区tr| 欧美色爱综合网| 国产91露脸合集magnet| 午夜一区二区三区在线观看| 亚洲国产精品ⅴa在线观看| 欧美浪妇xxxx高跟鞋交| 99久久综合精品| 激情久久五月天| 日韩精品午夜视频| 一区二区在线观看免费 | 五月婷婷久久综合| 中文字幕在线不卡国产视频| 精品成人私密视频| 欧美伦理视频网站| 色综合天天综合网国产成人综合天 | 亚洲视频在线一区| 久久久国产精品午夜一区ai换脸| 久国产精品韩国三级视频| 午夜精品久久久久久久久久| 中文字幕一区二区三区在线观看| 国产精品主播直播| 日韩精品免费专区| 午夜激情久久久| 午夜精品久久久久影视| 亚洲视频一区二区在线观看| 日本一区二区免费在线观看视频| 成人永久aaa| 国产揄拍国内精品对白| 国产在线播放一区三区四| 久久av资源网| 激情伊人五月天久久综合| 久久se这里有精品|