VB拖放講解,填補網路空白(個人認識過程)

2022-03-25 08:27:46 字數 3686 閱讀 2235

對於拖拽,我一直沒有乙個明確的認識,今天發現了這個問題,馬上著手解決(發現問題與解決問題的無縫結合,不能放到明天),認識到自己**不會是一種學問,解決更是一種學問。

首先,我站在巨人的肩膀上

說到拖拽,涉及到兩個事件:dragdrop、dragover,必須把控制項的dragmode屬性設為1(1為自動,預設為0手動)才可以發生,該控制項不再接收click事件和mousedown事件。(有人用到mousedown和mouseup來記錄位置,用這兩個事件的說明他根本沒理解拖拽的用法!)。

我們先來看看dragdrop事件(以窗體的為例)

private sub form_dragdrop(source as control, x as single, y as single)

end sub

這個事件是在拖拽到目的位置鬆開滑鼠時發生的。

還要先介紹一下drag方法:控制項.drag整數,整數範圍為0,1,2含義分別為:0取消拖動操作,1開始拖動操作,2結束操作。(放在mouseup中用於通知拖放結束,這都源自於資料,開始我也不知道,但實際測試發現不加也可以。。。。)

要使用乙個事件,必須先了解他的引數。source永遠是指的被拖拽的物件(即代替按住不放的控制項),x,y從表面理解應該是位置,網上的資料這樣說:引數x、y為鬆開滑鼠按鈕時光標的位置。看似沒什麼問題,於是我寫了如下**:

private sub command1_mouseup(button as integer, shift as integer, x as single, y as single)

command1.drag 2

end sub

private sub command1_dragdrop(source as control, x as single, y as single)

source.move x, y

print x, y

end sub

理解是:在鬆開滑鼠時觸發dragdrop事件,source代表被拖拽的按鈕物件,x、y是鬆開滑鼠時的游標座標,理論上按鈕是應該換位置的,但實際情況是按鈕不動。

繼續查閱資料,是這樣說的:拖動物件的dragdrop事件不是用來存放有關放開物件時執行某些指令的地方。而應將這些指令放到背景的dragdrop事件中或者拖動物件所放開的目標控制項中。恍然大悟,原來這個事件處理是要放在背景控制項或者目標控制項中的,是啟用的它人事件,而不是自己處理。

就是這乙個不知道,引出了一系列問題。顯然上邊的**是無法實現的,因為dragdrop事件要使用背景-----窗體的。但當我點選按鈕時它的位置會變,為什麼???感覺告訴我問題就出在x、y這兩個位置引數上!可以這樣理解:當我點選按鈕時,相當於以按鈕為背景,同時按鈕又是乙個被拖拽的物件,所以觸發了按鈕的dragdrop事件,此時source代表的又是本按鈕,所以位置發生了變化。再看看點選完按鈕的位置,基本上是到窗體的左上角。乙個瞬間的猜測:這個x、y位置引數是在背景控制項或者目標控制項的位置,是乙個相對的位置!馬上來驗證一下,我們點按鈕的左上角,在按鈕裡左上角據相當於窗體的左上角,它們的座標是都是(0,0),這時候我們會發現按鈕馬上移動到了窗體左上角(0,0)的位置!繼續點,很清晰的看出:游標相對於按鈕左上角的座標就是按鈕左上角在窗體上的座標。(單位都是緹)。這說明我們的猜測是正確的!每個控制項內部左上角座標都為(0,0),拖拽時游標在背景的相對位置或者目標控制項的相對位置將直接反映在被拖拽物件在背景的位置。為了更好的理解,可以試試下邊的例子:

private sub command2_dragdrop(source as control, x as single, y as single)

source.move x, y

end sub

private sub command1_mouseup(button as integer, shift as integer, x as single, y as single)

command1.drag 2

end sub

當我們把按鈕1拖拽到按鈕2上時,觸發了目標控制項按鈕2的dragdrop事件,此時x、y是游標在按鈕2的相對位置,source是被託物件按鈕1,此時按鈕1在背景(窗體)的位置就是游標相對於按鈕2的位置。

有了以上深刻的理解和認識,我們再來研究拖拽思路就很清晰了。於是網路上的**就可以很好的理解。

private sub form_dragdrop(source as control, x as single, y as single)

source.move (x - source.width / 2), (y - source.height / 2)

end sub

private sub command1_mouseup(button as integer, shift as integer, x as single, y as single)

command1.drag 2

end sub

相信你現在一看就懂了!還是提示一下source.move (x - source.width / 2), (y - source.height / 2)個人認為不是很好,因為拖拽按鈕時只有游標在按鈕正中間時,拖拽才是準確的,其他情況雖然不是很準,但基本也可以了,如果我改進的話,我會第一時間貼出的。。。。。

如果我們繼續觀察,力求完美,依然會發現問題!問題是:當拖拽控制項(按鈕)時,如果游標不出按鈕的範圍,它是不動的,這與我們的期望是不符的!這時候我們有了上邊的研究作為基礎,可以很輕易的解決這個問題!完美**如下:

private sub command1_dragdrop(source as control, x as single, y as single)

command1.left = command1.left - (source.width / 2 - x)

command1.top = command1.top - (source.height / 2 - y)

end sub

private sub form_dragdrop(source as control, x as single, y as single)

source.move (x - source.width / 2), (y - source.height / 2)

end sub

private sub command1_mouseup(button as integer, shift as integer, x as single, y as single)

command1.drag 2

end sub

如果弄懂了我所說的,可以看出只不過是多了乙個按鈕的dragdrop事件。在游標不出按鈕時,相當於以按鈕為背景,按鈕又為物件,此時不觸發窗體的dragdrop事件,而是觸發按鈕的dragdrop事件,所以加以處理就可以了!(很完美,拖哪到哪,隨便怎麼拖!具體運算方法就留給讀者了,不多解釋了)

最後,我們要學會自己發現問題,不能僅僅滿足於別人的見解,發散思維,設想出多種情況,通過發現問題與解決問題,才能使印象深刻,知識成網,達到不需要記憶,永遠也不會忘記的效果!

VB的檔案拖放實現

vb中,很多控制項都可以實現拖放功能。拖放功能有內部控制項間的拖放和由程式外部對程式本身的拖放。檔案拖放應該使用oledragdrop事件,而不是dragdrop事件。oledragdrop事件的語法如下 private subobject oledragdrop data as dataobjec...

VB控制項間的拖放

新建工程,放置控制項picture1,text1,text2,複製下面的 執行 text1和text2可以互相拖放,也可以將picture1拖放給text1,text2.private subform load picture1.oledragmode 1 text1.oledropmode 1 t...

使用VB實現OLE拖放功能

在窗體中新增乙個image控制項,在它的imgdrop oledragdrop過程中新增如下 private sub imgdrop oledragdrop data as dataobject,effect as long,button as integer,shift as integer,x ...