win32拖拽編程

本文由作者鄒啟文授權(quán)網(wǎng)易云社區(qū)發(fā)布。


在郵箱大師PC版中,我們需要實(shí)現(xiàn)一個(gè)功能:賬號(hào)和郵件夾拖拽排序。

  1. 準(zhǔn)備?
    封裝win32 API。我們使用到的API有,?
    ImageList_CreateImageList_Destroy、?
    ImageList_AddImageList_AddMasked、ImageList_Remove、?
    ImageList_BeginDrag、ImageList_DragEnter、ImageList_EndDrag、ImageList_DragLeave、?
    ImageList_DragMove、ImageList_SetDragCursorImageImageList_DragShowNoLock。?
    For more information,see?Using?Image?Lists

  2. Drag開始?
    攔截鼠標(biāo)的LButtonDown消息,判斷point所在的控件是否符合拖拽要求,如果符合,記住狀態(tài)(這里使用bool will_drag_和MailFolderNode* drag_from_標(biāo)識(shí)可以拖拽,使用bool is_draging_標(biāo)識(shí)正在拖拽中,使用MailFolderNode* drag_to_標(biāo)識(shí)接受控件)

  3. Drag進(jìn)行中?
    攔截鼠標(biāo)的MouseMove消息,判斷will_drag_,如果是,那么需要做如下操作:?
    ->ImageList_Create創(chuàng)建ImageList對(duì)象?
    ->ImageList_AddMasked加入拖拽時(shí)將要顯示的圖像?
    ->ImageList_BeginDrag即將開始拖拽,并設(shè)置鼠標(biāo)在拖拽圖像中的位置?
    ->ImageList_DragEnter進(jìn)入拖拽,并設(shè)置拖拽圖像的位置?
    ->修改will_drag_為false,is_draging_為true,保證上面幾步只做一次?
    ->判斷point是否在拖拽接受范圍內(nèi),以及point對(duì)應(yīng)控件是否接受拖拽(及時(shí)更新drag_to_)?
    ->如果是,那么執(zhí)行ImageList_DragMove、ImageList_DragShowNoLock(TRUE)、SetCursor(LoadCursor(NULL, IDC_ARROW));?
    ->如果不是,那么執(zhí)行ImageList_DragShowNoLock(FALSE)、SetCursor(LoadCursor(NULL, IDC_NO));

  4. Drag結(jié)束?
    攔截鼠標(biāo)的LButtonUp消息,如果is_draging_,那么執(zhí)行ImageList_EndDrag、ImageList_DragLeave、ImageList_Destroy,然后根據(jù)drag_from_和drag_to_處理本次拖拽操作。

  5. 問題?



    Ⅰ、如何使拖拽圖像背景透明??
    使用CreateCompatibleBitmap創(chuàng)建位圖,調(diào)用FillRect將位圖背景刷成白色RGB(255,255,255);?
    在ImageList_Create時(shí)指定ILC_COLOR32 | ILC_MASK;?
    調(diào)用ImageList_AddMasked(bitmap, RGB(255,255,255));?
    至此,拖拽圖像中的白色會(huì)與mask'中和'?

    Ⅱ、在拖拽時(shí)出現(xiàn)窗口繪制被'破壞',并且殘留痕跡??
    這是由于在調(diào)用ImageList_DragEnter時(shí)鎖定了窗口導(dǎo)致,我們使用NULL代替HWND即可解決此問題。同時(shí),由于鎖定導(dǎo)致了我們?cè)谕献r(shí)對(duì)窗口的繪制無法生效的問題亦可解決。另,記得在拖拽結(jié)束時(shí)ImageList_DragLeave(NULL);?

    Ⅲ、ImageList_BeginDrag和ImageList_DragEnter中的位置是何含義??
    在ImageList_BeginDrag中,此處位置為鼠標(biāo)圖標(biāo)相對(duì)于拖拽圖像的位置。?
    在mageList_DragEnter中,此處位置為鼠標(biāo)相對(duì)于HWND的位置,如果HWND為NULL,那么便是相對(duì)于屏幕的位置。?

    Ⅳ、ImageList_DragShowNoLock含義是什么??
    參數(shù)BOOL表示是否顯示拖拽圖像。當(dāng)拖拽move在可接受控件時(shí),顯示拖拽鼠標(biāo),更改鼠標(biāo)樣式(或使用ImageList_SetDragCursorImage設(shè)置自定義鼠標(biāo)樣式,注意此時(shí)需隱藏ShowCursor(FALSE));否則,不顯示拖拽圖像,并顯示IDC_NO不可操作樣式。?

    Ⅴ、will_drag_的標(biāo)識(shí)是否多余??
    為何要等到MouseMove再去真正開始drag?因?yàn)檎5膯螕舨僮鳎覀儾幌M吹酵献D像,因此設(shè)置此標(biāo)記。實(shí)際應(yīng)用中發(fā)現(xiàn),有時(shí)候單擊時(shí)發(fā)生'抖動(dòng)',此時(shí)也出現(xiàn)拖拽圖像,因此我們加入了延時(shí),在按下100ms后才將will_drag_設(shè)置成true,可在一定程度上減小抖動(dòng)出現(xiàn)拖拽圖像的情況。


免費(fèi)領(lǐng)取驗(yàn)證碼、內(nèi)容安全、短信發(fā)送、直播點(diǎn)播體驗(yàn)包及云服務(wù)器等套餐

更多網(wǎng)易技術(shù)、產(chǎn)品、運(yùn)營(yíng)經(jīng)驗(yàn)分享請(qǐng)?jiān)L問網(wǎng)易云社區(qū)。


相關(guān)文章:
【推薦】?Docker小白使用筆記
【推薦】?多大規(guī)模的數(shù)據(jù)才值得用大數(shù)據(jù)的方式來處理?
【推薦】?線上日志集中化可視化管理:ELK

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 之前寫過一篇瀏覽器事件的相關(guān)操作和事件運(yùn)行的原理——JavaScript瀏覽器事件解析。這一篇主要寫一些常用的事件...
    faremax閱讀 1,729評(píng)論 0 0
  • H5 meta詳解 viewport width:控制 viewport 的大小,可以指定的一個(gè)值,如果 600,...
    FConfidence閱讀 900評(píng)論 0 3
  • 著名作家賈平凹說:“會(huì)活的人,或者說取得成功的人,其實(shí)懂得了兩個(gè)字:舍得。不舍不得,小舍小得,大舍大得?!鄙岬蒙?..
    劉歡歡_閱讀 590評(píng)論 0 1
  • 長(zhǎng)亭離歌 仿佛一切的事情都已經(jīng)過去,林府還是如以前一樣,不曾有過什么改變,林無風(fēng)的到來給林府帶來無盡的歡樂,...
    小河邊上閱讀 414評(píng)論 1 14
  • 相處的第三個(gè)月,小暖依然對(duì)我發(fā)脾氣。理由是,和她在一起的大部分時(shí)間,我都在看手機(jī)。 事情在昨晚達(dá)到了不可調(diào)和的地步...
    段不可閱讀 7,636評(píng)論 90 144

友情鏈接更多精彩內(nèi)容