9. ¶i¶¥¨Ï¥Îªí³æ¤Î¹ï¸Ü¤è¶ô

ªí³æ(Form)¦Û±q­º¦¸¦bVisual Basic 1.0¥X²{¥H¨Ó¡A¤w¸g¦³¤F«Ü¦hªº§ï¶i¡AµM¦Ó¦h¼Æªºµ{¦¡³]­p¤H­û«o¨S¯àµ½¥Î¨ì³o¨Ç·sªº¥\¯à¡C¤j¦h¼Æªº±¡ªp¤U¡A¥L­Ì¤´µM©µ¥Î¦bª©¥»3.0¤¤©Ò¨Ï¥Î¤èªk¡A«o¨Ã¤£ÁA¸Ñ¨ä¹êªí³æ¤º³¡ªº¹B§@¤w¸g¦³¤F«Ü¤jªº§ïÅÜ¡C¦b¥»³¹¤¤¡A§Ú­Ì±NµÛ­«±´°Q¤@¯ëªí³æ¥H¤Î¦h­«¤å¥ó¬É­±(MDI)ªí³æªº¶i¶¥¨Ï¥Î¡A¸ÑÄÀ¦p¦ó»s§@¤@­Ó°Ñ¼Æ¤Æªºªí³æ¤¸¥ó¡A¤]±N¹ê§@¥i¤ä´©©ì©ñ(drag-and-drop)ªºÀ³¥Îµ{¦¡¡C¥t¥~§Ú­Ì±N±Ô­z´X­Ó¦bª©¥»6.0¤¤·s¼Wªº¥\¯à¡A¥]¬A¤F°ÊºA·s¼W±±¨î¶µ¡A¥H¤Î¨ã¦³¯àÂǥѳB²z¦hºØ¸ê®Æ«¬ºA¦Ó¹F¨ì­«ÂШϥΥتºªº¸ê®Æ¾É¦V(Data-Driven)ªí³æ¡C

ªí³æªº¼Ð·Ç¥Îªk
¡@

¦b ²Ä¤G³¹ §Ú­Ì¤w¸gÁ¿¸Ñ¤F³\¦h¦³Ãöªí³æªºÄÝ©Ê¡B¤èªk¡B¤Î¨Æ¥ó¡C¦b³o¤@³¹¡A§Ú­Ì±N»¡©ú¦p¦ó±Nª«¥ó¾É¦Vµ{¦¡³]­pÀ³¥Î¦bªí³æ¤W¡A±Ð±z¦p¦ó§Q¥Î³o­Ó§Þ¥©¨Ó¼g¥X¦³®Ä²v¡B¨S¦³¿ù»~(Bug-Free)ªºµ{¦¡¡C

§âªí³æ·í§@ª«¥ó
¡@

­º¥ý¡A§Ú­Ì¥²»ÝÁA¸Ñ¦bVisual Basic¤¤¡A¤°»ò¬Oªí³æ¡C¨Æ¹ê¤W¡A±qª©¥»4.0¥H«á¡Aªí³æ´N¬O¤@­Óª«¥ó¼Ò²Õ¥[¤W¤@­Ó³]­p®v(Designer)¡C±z¥i¥H¦^·Q²Ä¤G³¹©ÒÁ¿ªº¡A³]­p®v¬O¤@­Ó¾ã¦Xªºµo®iÀô¹Ò¼Ò²Õ¡A¥i¥HÅýµ{¦¡³]­p¤H­û§Q¥Îµøı¤Æªº¬É­±¥h³]©wª«¥ó°õ¦æ®É´ÁªºªºÄÝ©Ê¡C

§Q¥Îªí³æ³]­p®v¡A±z¥iÂǥѩì©Ô±±¨î¶µ¡A³]©wªí³æ¤W±±¨î¶µªº¦UºØÄÝ©Ê¡AÅý±z¦b³]­p®É´Á¡A¥h©w¸q¤@­Óªí³æªº¥~Æ[¡C·íÀ³¥Îµ{¦¡°õ¦æ®É¡AVisual Basic§Y®Éªº§â³o¨Ç¸ê°TÂàĶ¦¨¹ïÀ³ªºWindow API¨Ó²£¥Í¥Dµøµ¡¡A¥H¤Î¨º¨Ç¦b¤W­±ªº±±¨î¶µ¡C¦Ó¤@­Ó¨å«¬ªºVisual Basic±±¨î¶µ¡A­nÂàĶ¦¨¬Û¹ïÀ³ªºC©ÎC++µ{¦¡½X¡A¥i¯à³£­nªø¹F¦n´X¦Ê¦æ¡A©Î³\±z¤w¸gÁA¸Ñ¬°¤°»òVisual Basic¯à¦bµu®É¶¡¤º¦¨¬°³]­pWindowµ{¦¡³Ì¨üÅwªïªº»y¨¥¡C

§Ú­Ì¥i¥H«Ü®e©ö¦aÃÒ©úªí³æ¥u¬O¤@­Ó¨ã¦³¨Ï¥ÎªÌ¤¶­±ªºª«¥ó¡C°²³]¦b±zªºÀ³¥Îµ{¦¡¤¤¦³¤@­Ó¥s°µ frnDetails ªºªí³æ¡A±z¥i¥H§Q¥Îª«¥óªºNew¤èªk¨Ó²£¥Í¤@­Óª«¥ó¹êÅé¡G

Dim frm As frmDetails
Set frm = New frmDetails
frm.Show

­nÃÒ©úªí³æ¬O¤@­Óª«¥ó¡A«Ü­«­nªº¤@ÂI¡A´N¬O­n¹³¤@¯ëª«¥ó¨ã¦³ÄÝ©Ê¡B¤èªk¡B¤Î¨Æ¥ó¡CÁ|¨Ò¨Ó»¡¡A±z¥i·s¼W¤@­Ó¬Æ¦Ü¦h­ÓªºPublicÄÝ©Ê¡A±Nªí³æ¤Wªº±±¨î¶µ°µ«Ê¸Ë¡A½Ð¬Ý©³¤U³o¬qµ{¦¡¡G

' Inside the frmDetails form 
Public Property Get Total() As Currency
    Total = CCur(txtTotal.Text)
End Property

¬Û¦P¦a¡A±z¤]¥i·s¼W¤@¨ÇPulbic ªº¤èªk¡AÅý¥Dµ{¦¡¯à°÷³z¹L©I¥s³o¨Ç¤èªk¡A¨ÓÅýªí³æ§¹¦¨¤@¨Ç¤u§@¡A¨Ò¦pÅý¥¦¦C¦L¥X¦Û¤vªº¤º®e¡G

' Note that Sub, Function, and Property procs are Public by default.
Sub PrintOrders()
    ' Here you place the code that prints the form's contents.
End Sub

¦bªí³æ¼Ò²Õ¥~¡A±z¥i¥H¹³¤@¯ëªºª«¥ó¤@¼Ë¨ú±o¥¦ªºÄÝ©Ê¡G

Dim Total As Currency
Total = frm.Total()
frm.PrintOrders

ªí³æ»P¤@¯ëª«¥ó³Ì­«­nªº¤£¦PÂI¬Oªí³æ¤£¯à³Q«Å§i¦¨Public¡AÅý¨ä¥¦ªºÀ³¥Îµ{¦¡³z¹LCOMªº¤è¦¡¨Ó¦s¨ú¡C

¦bªí³æ¤¤ÁôÂ꺥þ°ìÅܼÆ
¡@

«Ü¥Ù¬Þ¦a¡A´N¹³§Ú­Ìª¾¹D­n¨Ï¥Îª«¥ó«e¥²¶·¥ý­n±Ò©l(initialize)¥¦¡A¹ï¦¹¦Ó¨¥¡A§Ú­Ì¥²»Ý§âªí³æ¬Ý°µ¬O¤@­Ó¡u¯S®í¡v«¬ºAªºª«¥ó¡C¦]¬°±z¥i¥Hª½±µ¨Ï¥Î¤@­Óªí³æ¡A¦Ó¤£¥Î¥ý°µ±Ò©lªº°Ê§@¡C¨Ò¦p¦b¤U­±ªºµ{¦¡¤ù¬q¡A±z¤£¥Î¥ý©ú½Tªº«Ø¥ßfrmDrails ªí³æ¡G

Private Sub cmdDetails_Click()
    frmDetails.Show
End Sub

¬JµM§Ú­Ì»¡ªí³æ¬O¤@­Óª«¥ó¡A¬°¤°»ò¤W­±ªºµ{¦¡¤£·|²£¥Íerror 91: "Object variable or With block variable not set"¡H¨ä¹ê³o­Ó°ÝÃD¤w¸g¦s¦b¤@¬q®É¶¡¤F¡C·íª©¥»4.0µoªí®É¡A·L³n¤uµ{®v¥²»Ý½T«O¦bª©¥»3.0¡A¬Æ¦Ü¤§«eª©¥»µo®iªºµ{¦¡¡A¯à°÷¦b·sª©¥»¤W¥¿½T¦a°õ¦æ¡C²³æªº»¡¡A­Y¦bª©¥»3.0©Ò¶}µoªº±M®×¡AµLªk¦bª©¥»4.0¤W¨Ï¥Î¡A¨ºª©¥»4.0«K¬O¤@­Ó¥¢±Ñªºª©¥»¡C©ó¬O¤uµ{®v­Ì·Q¥X¤@­Ó¬J²³æ¤SÀu¶®ªº¸Ñ¨M¤èªk¡C¦b¥Ø«eªºÀ³¥Îµ{¦¡¤¤¡A½sĶµ{¦¡²£¥Í¤F¤@­Ó»Pªí³æ¬Û¦P¦WºÙªº¥þ°ìÅܼơA¦Ó³o­ÓÅܼƬOÁôÂð_¨Óªº¡G

' (Note: you will never actually see these declarations.)
Public frmDetails As New frmDetails
Public frmOrders As New frmOrders
' (Same for every other form in the application)

·í±zªºµ{¦¡½X°Ñ¦Ò¨ì³o­Óªí³æªº¹êÅé®É¡A¨Ã¤£¬Oª½±µ¤Þ¥Î¨ìfmDetailªºªí³æª«¥ó¡A¦Ó¬O¤Þ¥Î¨ì»P³o­Óªí³æ¦P¦Wªº¥þ°ìÅܼơC¥¿¦]¬°³o­ÓÅܼƬO¦Û°Ê²£¥Íªº¡AVisual Basic¦b±z¤Þ¥Î¨ì³o­ÓÅܼƮɡA¥ß¨è·|«Ø¥ß·sªºªí³æª«¥ó¡C³o­Ó§Q¥ÎÁôÂÃ¥þ°ìÅܼƪºÁo©ú§Þ¥©¡A¦¨¥\ªºÅýµ{¦¡µo®i¤H­û¯à°÷»´ÃPªº§â¦bª©¥»3.0¤¤µo®iªºµ{¦¡¡A¨Ï¥Î¦bª©¥»4.0©Î§ó·sªºª©¥»¤W¡C¦ý¬O¡Aµy«á±z¤]·|¬Ý¨ì³o¨ÇÁôÂêºÅܼƷ|³y¦¨¼ç¦bªº°ÝÃD¡A³o¬O±z¥²¶·­nª`·Nªº¡C

²M°£ªí³æ¹êÅ骺°ÝÃD
¡@

¬°¤F´y­z³o­Ó¤w³QÃÒ©ú±`¦b¨Ï¥Îªí³æ¤W¸I¨ìªº°ÝÃD¡A§Ú­Ì«Ø¥ß¤@­Ó²³æªºfrmLoginªí³æ¡A¥¦·|­«Âи߰ݨϥΪ̩m¦W¤Î±K½X¡Aª½¨ì¨âªÌ³£¥¿½T¬°¤î¡C³o­Óªí³æ¾Ö¦³¨â­ÓPublicªºÄÝ©Ê¡A UserName¤ÎPassword¡A¥¦­Ì·|¦b Unload ¨Æ¥ó¤¤¡A¤À§O³Q«ü©w¬°¦btxtUserName¤ÎtxtPassword±±¨î¶µªº­È¡G

Public UserName As String
Public Password As String

Private Sub cmdOK_Click()
    ' Unload this form only if password is OK.
    If LCase$(txtPassword) = "balena" Then Unload Me
End Sub

Private Sub Form_Load()
    ' Move property values into form fields.
    txtUserName = UserName
    txtPassword = Password
End Sub

Private Sub Form_Unload(Cancel As Integer)
    ' Move field contents back into public properties.
    UserName = txtUserName
    Password = txtPassword
End Sub

±z¥i¥HÅýfrmLoginªí³æÅã¥Ü¥X¨Ï¥ÎªÌ©Ò¿é¤Jªº­È¡G

' Code in frmMain form
Private Sub cmdShowLogin_Click()
frmLogin.Show vbModal
' Execution gets here only if password is OK.
MsgBox frmLogin.UserName & " logged in."
End Sub

­n´ú¸Õªí³æ¬O§_¥¿±`¹B§@¡A¥ý°õ¦æ¥Dªí³æ¡AÂI¿ïcmdShowLogin«öÁä¡AµM«á¿é¤J¨Ï¥ÎªÌ¦WºÙ¤Î±K½X(¦p¹Ï9-1)¡C·ífrmMain¥Dªí³æ¦A«×¨ú±o±±¨îÅv®É¡A¥¦·|Åã¥Ü¤@­Ó°T®§¹ï¸Ü¤è¶ô¡Cªí­±¤W¦ü¥G¤@¤Á¹B§@¥¿±`¡A°²¦p±z¦A¦¸«ö¤ULogin«ö¶s¡AfrmLoginªí³æ±N¦A³Q±a¥X¡A¦ý¬O³o¤@¦¸¡A¤§«e¨Ï¥ÎªÌªº¦WºÙ¤Î±K½X«o·|ª½±µÅã¥Ü¦bªí³æ¤W¡C³o¥i¤£¬O§Ú­Ì©Ò§Æ±æªº«O±K¤è¦¡¡I


¡@

¹Ï9-1 Login ½d¨Òµ{¦¡

­nÁA¸Ñ°ÝÃDµo¥Í¦b­þ¸Ì¡A½Ð§â¤U­±³o¬qµ{¦¡½X¥[¤Jªí³æ¼Ò²Õ¤¤¡G

Private Sub Form_Initialize()
    Debug.Print "Initialize event"
End Sub
Private Sub Form_Terminate()
    Debug.Print "Terminate event"
End Sub

²{¦b¡A°²¦p±z­«ÂЦa¨Ì·Ó§Ú­Ì­è¤~ªº¨BÆJ¥h°õ¦æµ{¦¡¡A±z·|µo²{¡A¦bµ{¦¡°Ñ¦Ò¨ì frmLogin ªº®É­Ô·|¥ß¨èµo¥Í Initialize ¨Æ¥ó¡A¤Ï¤§¡ATerminate ¨Æ¥ó«o±q¥¼µo¥Í¡C´«¥y¸Ü»¡¡A±z²Ä¤G¦¸©ÒÅã¥ÜªºfrmLoginªí³æ¡A¬O¦b±z²Ä¤@¦¸°õ¦æ®É©Ò«Ø¥ßªº¹êÅé¡C³o­Óªí³æ³Q¥¿±`ªºUnload¡A¦ýVisual Basic«o¨S¦³ÄÀ©ñªí³æ¹êÅ骺¸ê®Æ°Ï(Data area)¡A¤]´N¬O»¡¡A¤£ºÞ¬OPrivate©ÎPublicÅܼơA³£¤´µM¦s¦b©ó°O¾ÐÅ餤¡C¦]¬°³o­Ó­ì¦]¡A²Ä¤@¦¸¿é¤Jªº¨Ï¥ÎªÌ©m¦W¤Î±K½X·|¥Ã»·¦s¦b©ó°O¾ÐÅ餤¡A´N¹³¨â­ÓTextBox±±¨î¶µ¤¤©ÒÅã¥Üªº¡C¦b¯u¥¿¶}µoÀ³¥Îµ{¦¡®É¡A³o­Ó¯S©Ê±N¥i¯à³y¦¨¤@¨Ç«ÜÃø³Qµo²{ªº¿ù»~¡A¦]¬°³oºØÃþ«¬ªº¿ù»~©ó¨Ï¥ÎªÌ¤¶­±¤W¬O¬Ý¤£¨ìªº¡C

­nÅý¤W­±ªºµ{¦¡¥¿±`¹B§@¡A¥i¥H±j­¢Visual BasicÄÀ©ñªºªí³æ¹êÅé¥H½T«O¤U¦¸·|¦A«Ø¥ß¤@­Ó¥þ·sªº¹êÅé¡C¦³¨â­Ó¤èªk¥i¥H¨Ó¹F¦¨¡A³Ì±`¥Îªº´N¬O¦bShow¤èªk«á¡A§âªí³æÅܼƳ]¬°Nothing¡G

Private Sub cmdShowLogin_Click()
    frmLogin.Show vbModal
    MsgBox frmLogin.UserName & " logged in."
    ' Set the hidden global form variable to Nothing.
    Set frmLogin = Nothing
End Sub

¥t¥~´N¬O¨Ï¥Î¤ñ¸ûÃþ¦üª«¥ó¾É¦VÆ[©Àªº¤è¦¡¡C±z¥u­n²³æªº«Å§i¤@­Ó»Pªí³æ¦WºÙ¬Û¦Pªº°Ï°ìÅܼơA³o¼Ë«K¯à¨ú¥N¥þ°ìÅܼơG

Private Sub cmdShowLogin_Click()
    Dim frmLogin As New frmLogin
    frmLogin.Show vbModal
    MsgBox frmLogin.UserName & " logged in."
End Sub

²{¦b±z°õ¦æ³o¤äµ{¦¡¡A±N·|µo²{Visual Basic¤w¸g¥¿½Tªºµo¥Í Form_Terminate ªº¨Æ¥ó¡A¦]¦¹§Ú­Ì¥i¥H½T»{ªí³æ¤w¸g³Q§¹¥þÄÀ©ñ¡C±q³o­Ó§Þ¥©¡A¥i¥Hµo²{¦³½ìªº¤@ÂI¡A±z¥i¥H¤@¦¸¦P®É«Ø¥ß¦h­Óªí³æ¹êÅé¡A¦p¹Ï 9-2¡C

Private Sub cmdShowDocument_Click()
    Dim TextBrowser As New TextBrowser
    TextBrowser.Filename = txtFilename.Text
    ' Show the form, making it a child form of this one. 
    TextBrowser.Show, Me
End Sub


¡@

¹Ï9-2 ¨Ï¥Î©ú½Tªºªí³æÅܼơA±z¥i¥H«Ø¥ß¨ÃÅã¥Ü¦h­Ó¬Û¦Pªºªí³æ¹êÅé¡C©Ò¦³ªº¤lªí³æ³£·|Åã¥Ü¦b¤÷ªí³æªº¤W¼h¡A§Y¨Ï¤÷ªí³æ¤w¸g±o¨ì¾nÂI(focus) ¡C

¤p¯µ³Z

ªí³æ Show ¤èªk´£¨Ñ¤F²Ä¤G­Ó¿ï¾Ü¶µ¤Þ¼Æ¡AÅý±z«ü©w©ÒÅã¥Üªí³æªº¤÷ªí³æ¬°¦ó¡C·í±z¶Ç¤J­È¨ì³o­Ó¤Þ¼Æ¡A·|µo¥Í¨â¥ó¦³½ìªº¨Æ±¡¡G¤lªí³æ¤@©wÅã¥Ü¦b¤÷ªí³æªº¤W¼h¡A§Y¨Ï¤÷ªí³æ¤w¸gÀò±o¾nÂI¡C¨ä¦¸¡A·í¤÷ªí³æÃö³¬©Î³Ì¤p¤Æ®É¡A¤lªí³æ¤]¦Û°ÊªºÃö³¬©Î³Ì¤p¤Æ¡C±z¥i¥H§Q¥Î³o­Ó¯S©Ê«Ø¥ß¤@­Ó¥iÂ\¤u¨ã¦C¡B½Õ¦â½L©Î¬O¤@²Õ¹Ï¥Üµ¥ªº¯B°Ê¦¡¤lªí³æ¡C¦¹®É±z¥i±N¤lªí³æ BorderStyle ³]¬°4-Fixed ToolWindow ©Î¬O5-Sizable ToolWindow¡C


±z¥i¥H¦bÀH®ÑCD¤¤§ä¨ì§¹¾ãªºfrmTextBrowserªí³æ¼Ò²Õªºµ{¦¡½X¡C½Ðª`·N³o­Ó¨Ò¤l³£¬O¨Ï¥Î«D¿W¦û¦¡ªºªí³æ¡C

·íªí³æÅܼƪº¥Í©R¶g´Áµ²§ô«á¡A±z¤´µM¥i¥H¬Ý¨ì¥¦ªºµe­±¡A¦¹®ÉVisual Basic¤£·|ÄÀ©ñªí³æªº¸ê®Æ°Ï¡Cª½¨ì¨Ï¥ÎªÌUnload³o­Óªí³æ¡AVisual Basic¦b Form_Unload ¨Æ¥ó«á¡A¥ß¨èIJµo Form_Terminate ªº¨Æ¥ó¡A¦¹®É¡A¸ê®Æ°Ï¤~·|³QÄÀ©ñ¡C³o­Ó¯S©Ê¦n¹³¹H¤Ï¤F¡u·íª«¥ó¤£¦A³Q¤Þ¥Î®É¡A´NÀ³¸Ó³Q¾P·´¡vªº³W«h¡A±µ¤U¨Óµ§ªÌ±N»¡©ú¨Æ¹ê¤W¡A§Ú­Ì¨Ã¤£¬O§¹¥þ¤£¦A°Ñ·Ó³o­Óªí³æ¡C

ªí³æ¶°¦X
¡@

ªí³æ¶°¦X(Forms collection) ¬O¤@­Ó¥þ°ì©Êªº¶°¦X¡A¥¦¥]§t©Ò¦³¤w¸g³Q¸ü¤Jªºªí³æ¡C¤]´N¬O»¡©Ò¦³¤w¸g³Q¸ü¤Jªºªí³æ³£·|³Q³o­Ó¶°¦X¤Þ¥Î¨ì¡A¦]¦¹´Nºâµ{¦¡¤¤¤w¤£¦A¦³¥ô¦ó¹ïªí³æªº¤Þ¥Î¡A¥¦­Ì¨ÌµM¤£·|³QÄÀ©ñ¡C³z¹L©³¤Uªº¨ç¦¡¡A±z¥i¥H±qªí³æ¶°¦X¨ú±o¹ï¥ô¦ó¤@­Óªí³æªº¤Þ¥Î(reference)¡G

Function GetForm(formName As String) As Form
    Dim frm As Form
    For Each frm In Forms
        If StrComp(frm.Name, formName, vbTextCompare) = 0 Then
            Set GetForm = frm
            Exit Function
        End If
    Next
End Function

°²¦p¦b¶°¦X¤¤¦³¬Û¦P¦WºÙªºªí³æ¡A«h¶Ç¦^¦WºÙ¬Û²Å¦Xªº²Ä¤@­Ó¡A±z¥i¥H¥Î©³¤Uªºµ{¦¡¡A³z¹Lªí³æªº¦WºÙ¨Ó¨ú±o¸Óªí³æªº¤Þ¥Î¡G

GetForm("frmLogin").Caption = "Login Form"

±z¥i¯à»Ý­nª`·Nªº¬O¡AGetForm ¨ç¼Æ©Ò¶Ç¦^ªº¬Oformªº«¬ºA¡C¤]´N¬O¶Ç¦^ªºªí³æ¥u¯à¨Ï¥Î¨ì¤@¯ëformÀ³¦³ªº¤èªk¤ÎÄÝ©Ê¡A¨Ò¦p Caption ¤Î ForeColor ÄݩʩάO Move »P Show ªº¤èªk¡A­Y±z­n¨Ï¥Î¦Û­qªºÄݩʩΤèªk¡A±z¥²»Ý©w¸q¤@­Ó«ü¨ì¬Y¤@¯S©wªí³æª«¥óªºÅܼơA¦A§â GetForm ¶Ç¦^ªºªí³æÂ૬(Cast)¦s¨ì¸ÓÅܼƤ¤¡G

Dim frm As frmLogin
Set frm = GetForm("frmLogin") = "Login Form"
username = frm.UserName

¥i­«½Æ¨Ï¥Îªºªí³æ
¡@

´N¹³ª«¥ó¼Ò²Õ¤@¼Ë¡A­Y§âªí³æ·í¦¨¬O¤@­Óª«¥ó¡A¨º´NÀ³¸Ó¨ã¦³¥i­«ÂШϥΪº¯S©Ê¡C¥i­«ÂШϥΪºªí³æ¥i¥HÀ³¥Î¨ì«Ü¦h¦a¤è¡A³Ì²³æªº´N¬O§Ú­Ì¦b ²Ä¤G³¹ ©ÒÁ¿ªº¡A§âªí³æ·í§@¬O¤@­Ó¼Ëª©¡CµM¦Ó­Y¦Aµy¥[¤@ÂI§Þ¥©¡A§Ú­Ì±N¥i³]­p¥X§ó¨ã¼u©Ê¡B¥i¥Î©Êªºªí³æª«¥ó¡C¦b¤U­±ªº´X¸`¤¤¡A§Ú­Ì±N§ó¶i¤@¨B´y­z³o¨Ç§Þ¥©¡C

¨Ï¥Î¦Û­qªºÄݩʤΤèªk
¡@

«Ü¦h°Ó·~À³¥Îµ{¦¡·|Åã¥Ü¥X¤é¾äÅý¨Ï¥ÎªÌ¦b¤W­±ª½±µ¿ï¾Ü¤é´Á¡CVisual Basic¤]´£¨Ñ¤@­ÓMonthView Micsrosoft ActiveX±±¨î¶µ(½Ð¬Ý ²Ä11³¹ )¡A¦ý¬O­Y¨Ï¥Î¦Û¤v³]­pªºªí³æ«h¥i¥H¦³¥H¤U´XÂI¦n³B¡GÁ|¨Ò¨Ó»¡¡A¥i¥HÅý§Ú­Ì¦Û­q¤j¤p(size)¡B¤é´ÁªºÅã¥Ü¤è¦¡¥H¤Î¥Nªí°²¤éªºÃC¦âµ¥µ¥¡C¤@¯ë¨Ó»¡¡A¦b¨Ï¥ÎªÌ¤¶­±¤W¨Ï¥Î¦Û­qªºªí³æ¥i¥H±a¨Ó³Ì¤jªº¼u©Ê¡A¦bÀH®Ñ¥úºÐ¤¤¡A±z¥i¥H¨ú±o¹Ï9-3¤¤frmCalendarªí³æªº§¹¾ãªºµ{¦¡½X¡C³o¨Ç¤é´Áªº«ö¶s¡A¬O¤@²Õ¥Ñ¦W¬°OptionButtonªº±±¨î¶µ°}¦C©Ò±Æ¦C¦Ó¦¨ªº¡A¨C­Ó«ö¶sªºStyleÄݩʳ£³]¬°1-Graphical¡C


¡@

¹Ï9-3 ¦Û­qªº¤é¾äªí³æ¡A³z¹L¦Û­qªºÄÝ©Ê¡A¤èªk¤Î¨Æ¥ó»P¥Dµ{¦¡°µ·¾³q¡C

frmCalendar ´£¨Ñ´X­ÓÄÝ©ÊÅý±z¦Û­q¥¦ªº¤¶­±¡A¨Ò¦p DialogTitle (³]©w¹ï¸Ü¤è¶ôªº¼ÐÃD)¡BFirstDayOfWeek ¤Î SaturdayIsHoliday (¦b³]©w¤é¾ä¥~Æ[«Ü¦³¥Î)¡C¤]´£¨Ñ¤@²ÕÄݩʨӨú±o¨Ï¥ÎªÌ©Ò¿ï¾Üªº¤é´Á¡GCancelPressed (·í¨Ï¥ÎªÌ¥¼°µ¥ô¦ó¿ï¾Ü®É¶Ç¦^True)¡BSelectedDate (¥iŪ¼g¤é´Á)¡BDay¡BMonth¤ÎYear (°ßŪ¡A¥i¶Ç¦^©Ò¿ï¾Üªº¤é¡B¤ë¡B¦~)¡C³o­Ó¼Ò²Õ¥u¦³¤@­Ó¦W¬° ShowMonth ªº¤èªk¡A¥¦¥i¥H¨Ì¾Ú©Ò¶Ç¤Jªº¤ë¥÷¡AÅã¥Ü¥X¸Ó¤ë¥÷ªº¤é¾ä¡A¤]¥i¥H±N¬Y¤@¯S©wªº¤é´Á°µ¼Ð°O¡G

Private Sub cmdCalendar_Click()
    Dim Calendar As New frmCalendar
    Calendar.DialogTitle = "Select a new date for the appointment"
    ' Highlight the current day/month/year.
    Calendar.ShowMonth Year(Now), Month(Now), Day(Now)
    ' Show the calendar as a modal dialog.
    Calendar.Show vbModal
    ' Get the result if the user didn't press Cancel.
    If Not Calendar.CancelPressed Then
        AppointmentDate = Calendar.SelectedDate
    End If
End Sub

¤@¯ë¦Ó¨¥¡A­n§âªí³æ·í¦¨¤@­Óª«¥ó¨Ï¥Î¡A¨º´NÀ³¸Ó´£¨Ñ¤@²Õ¤¶­±Åý¨Ï¥ÎªÌ¨Ó¦s¨úªí³æªº­ì¥Í(native)ÄÝ©Ê¡C¨Ò¦p¡AfrmCalendar ªí³æ¼Ò²Õ´£¨Ñ¤@­Ó DialogTitle ªº¦Û­qÄÝ©Ê¡A¨Ó¨ú¥N­ì¥»ªí³æªº Caption ÄÝ©Ê¡C¨Ï¥Î³o­Ó¤èªk¡A¥Î¤áºÝ´N¤£·|¯}Ãaªí³æª«¥óªº«Ê¸Ë(encapsulation)¡AÅý±z½T«Oª«¥ó¤º³¡ªº¥¿½T¹B§@¡C«Ü¿ò¾Ñ¦a¡A¦bªí³æª«¥ó¤¤¡A±z¨S¦³¿ìªk¥hÁקK¨ä¥¦À³¥Îµ{¦¡ª½±µ©I¥sªí³æ©Îªí³æ¤W±±¨î¶µªº­ì¥ÍÄÝ©Ê¡A©Î³\³o´N¬O¨É¨üªí³æª«¥ó©Ò±a¨Óªº¦n³B®É¦P®É»Ý¥I¥Xªº¥N»ù§a¡C

¼W¥[¦Û­qªº¨Æ¥ó
¡@

¦b¤W­±ªºµ{¦¡½X¤¤¡AfrmCalenderªí³æ¬O¥H¿W¦û¦¡ªº¤è¦¡Åã¥Ü¹ï¸Ü¤è¶ô¡A¤]´N¬Oµ{¦¡¤@ª½­nµ¥¨ì¹ï¸Ü¤è¶ô³QÃö³¬«á¡A¤~·|Ä~Äò°õ¦æ¤U¥h¡C·í¹ï¸Ü¤è¶ôÃö³¬®É¡A±µ¤U¨Óªºµ{¦¡½X´N·|Àˬdªí³æªºÄÝ©Ê¡A¨ú±o¨Ï¥ÎªÌ¿ï¾Ü¤é´Á¡CµM¦Ó¡A¦b¤j¦h¼Æ±¡ªp¤U¡A±z¥i¯à¶·­n¨Ï¥Î«D¿W¦û¦¡ªº¤è¦¡¨ÓÅã¥Ü¹ï¸Ü¤è¶ô¡C¦¹®É¡A±z¥²»Ý¾Ç²ß¤@­Ó¤èªk¨Ó±oª¾¨Ï¥ÎªÌ¦ó®ÉÃö³¬¹ï¸Ü¤è¶ô¡AµM«á¤~¥h¬d¸ß SelectedDate ÄÝ©Ê¡C±z¥i¥HÂǥѷs¼W¤@¹ï¦Û­qªº¨Æ¥ó¨Ó¹F¨ì¤W­zªº¥Øªº¡G

Event DateChanged(newDate As Date) 
Event Unload(CancelPressed As Boolean)

¦Û­q¨Æ¥ó¼W¥[¤FfrmCalendar¼Ò²Õªº¥i¥Î©Ê¡C´N¹³¤@¯ëªºª«¥ó¤@¼Ë¡A­n®·®»³o¨Ç¨Æ¥ó¡A±z¥²¶·¦bÅã¥Ü¤é¾ä¹ï¸Ü¤è¶ôªº¼Ò²Õ¶¥¼h(module-level)¼W¥[¤@­Ó WithEvents ÅܼơG

' In the frmMain form
Dim WithEvents Calendar As New frmCalendar

Private Sub cmdCalendar_Click()
    Set Calendar = New frmCalendar
    Calendar.DialogTitle = "Select a new date for the appointment"
    Calendar.ShowMonth Year(Now), Month(Now), Day(Now)
    Calendar.Show           ' Show as a modeless dialog box.
End Sub

Private Sub Calendar_DateChanged(newDate As Date)
    ' Show the date currently selected on a Label control.
    lblStatus.Caption = Format(newDate, "Long Date")
End Sub

Private Sub Calendar_Unload(CancelPressed As Boolean)
    If CancelPressed Then
        MsgBox "Command canceled", vbInformation
    Else
        MsgBox "Selected date: " & Format$(Calendar.SelectedDate, _
            "Long Date"), vbInformation
    End If
    ' We don't need this variable any longer.
    Set Calendar = Nothing
End Sub

»¡©ú

ŪªÌ¥i¯à·|°Ý¬°¤°»ò»Ý­n¤@­Ó¦Û­qªº Unload ¨Æ¥ó¡A±z¥i¯à¥H¬°·íÅܼÆCalendar ¤Þ¥ÎfrmCalendarªí³æ®É¡A¤]¤@¼Ë¥i¥H®·®»frmCalendarªº Unload ¨Æ¥ó¡C³o­Ó°²³]¨Ã¤£¥¿½T¡A¨Æ¹ê¤W¡ACalenader Åܼƥu¬O³æ¯Â«ü¦VfrmCalendarªº¦Û­q¤¶­±¦Ó¤w¡C¹³¼Ð·Çªí³æ©Ò¨ã³Æªº Unload¡BResize¡BLoad¡BPaint µ¥¨Æ¥ó¡A¨Ã¤£¯àÂǥѫ¬ºA¬° frmCalendar ªºÅܼƩҮ·®»¡C­n¯à®·®»³o¨Ç¨Æ¥ó¡A´N¥²¶·­n«Å§i¤@­Ó«¬§O¬° Form ªºÅܼơA¦b³o­Ó¨Ò¤l¤¤¡A§Ú­Ì¨Ï¥Î¦Û­qªº Unload ¨Æ¥ó¡A¹ê§@±N·|¤ñ¸û²¤Æ¡C


´N¹³¤@¯ëªº¼Ð·Çª«¥ó¼Ò²Õ¤@¼Ë¡A¨Ï¥Î¦Û­qªº¨Æ¥ó¡A±N·|¬°ªí³æ¼Ò²Õ±a¨Ó§ó¦hªº¼u©Ê¡C¼W¥[¤@­ÓChange-Likeªº¨Æ¥ó¡A´N¹³¦bfrmCalendar¼Ò²Õ¤¤ªº DataChanged ¨Æ¥ó¡A¥iÅý¨Ï¥ÎªÌ©¼¦¹¶¡ªº¤é´Á«O«ù¤@­P¡C±z¤]¥i¦Û­q¤@­Ó Progress ¨Æ¥ó¡A·íµ{¦¡³B²z®É¶¡¹Lªø®É¡A¥i¥Î¨ÓÅã¥Ü¶i«×¡A¦³Ãö¨Æ¥óªº¨Ï¥Î¡A½Ð°Ñ¦Ò ²Ä¤C³¹ ¡C

°Ñ¼Æ¤Æªºªí³æ
¡@

¤@­Óªí³æ¦b°õ¦æ®É´Á´£¨Ñ¤@²Õ¤èªk¤ÎÄÝ©Ê¡A¥i¥HÅý¥Dµ{¦¡¥Î¨Ó¨M©wªí³æÅã¥Üªº¥~Æ[¡A§Ú­ÌºÙ¤§¬°°Ñ¼Æ¤Æªºªí³æ¡A³z¹L°Ñ¼Æ¤Æ¥i¥HÅýªí³æ§ó¨ã­«ÂШϥΩʡC½Ð¬Ý¹Ï9-4¥i¥H§óÁA¸Ñµ§ªÌªº·N«ä¡Q¹Ï¤¤¨â­Ó¨ã¦³¿ï¶µ«ö¶sªºªí³æ¡A¹ê»Ú¤W¬O¬Û¦Pªºªí³æ¼Ò²Õ¡A¥¦­Ì¨Ì¾Ú¥Dµ{¦¡ªº»Ý­n¡A¦ÓÅã¥Ü¤£¦Pªº¥~Æ[¡C

°Ñ¼Æ¤Æªºªí³æ»s§@¤W¤ñ¸û§xÃø¡A­º¥ý¡A±z¥²¶·©w¸q¥X¤@²Õ¤èªk¤ÎÄݩʨÓÅý¨Ï¥ÎªÌ¨M©wÅã¥Üªí³æªº¥~Æ[¡C¨ä¦¸¡A±z¥i¯à­n¼g«Üªøªºµ{¦¡½X¨ÓÅýªí³æ¤W©Ò¦³ªº±±¨î¶µ¯à°÷¦b°õ¦æ®É´Á¡A¦Û°Ê±N¦Û¤vÅã¥Ü©óµe­±¥¿½Tªº¦ì¸m¤W¡C


¡@

frmOptionsªí³æ´£¨Ñ¤T­ÓÃöÁä¤èªkÅý±z·s¼W®Ø¬[(Frame Control)¡B®Ö¨ú¤è¶ô(CheckBox Control)¤Î¿ï¶µ«ö¶s(OptionButton)±±¨î¶µ¡G

Private Sub cdmOptionsOne_Click()
    Dim frm As New frmOptions

    ' Add a Frame control _ the first argument to this and following 
    ' methods is a unique ID code for the control being created.
    frm.AddFrame "F1", "First Group"
    ' Each subsequent AddOption and AddCheck method adds 
    ' a control inside the current frame, until another AddFrame
    ' method is issued.
    frm.AddOption "O1", "&1. First", True   ' Set the value to True.
    frm.AddOption "O2", "&2. Second"
    frm.AddOption "O3", "&3. Third"

    ' Add a second frame, with three radio buttons and two check boxes.
    frm.AddFrame "F2", "Second Group"
    frm.AddOption "O4", "&4. Fourth", True  ' Set the value to True.
    frm.AddOption "O5", "&5. Fifth"
    frm.AddOption "O6", "&6. Sixth"
    ' Tick this check box control.
    frm.AddCheck "C1", "&7. Check one", True  
    frm.AddCheck "C2", "&8. Check two"
    ' Show the form as a modal dialog.
    frm.Show vbModal

frmOptionsªí³æ¼Ò²Õªº Value ¤èªk·|¶Ç¦^±±¨î¶µªºID­È¡C±z¥i¥H¨Ï¥ÎID­È¨Ó¨ú±oCheckBox©Î¬OOptionButtonsªº Value ­È¡A¤]¥i¥Hª¾¹DOptionButton±±¨î¶µ¬O§_³Q¿ï¨ú¡G

' Continuing the cmdOptionsOne_Click procedure...
    If frm.CancelPressed Then
        MsgBox "Command canceled", vbInformation
    Else
        MsgBox "Option button in first frame: " & frm.Value("F1") _
            & vbCr &  "Option button in second frame: " _
            & frm.Value("F2") & vbCr _
            & "First checkbox : " & frm.Value("C1") & vbCr _
            & "Second checkbox: " & frm.Value("C2") & vbCr, _
            vbInformation, "Result of Options form"
    End If
End Sub

½Ð°Ñ¦Ò­ì©l½X¡A¬Ý¬ÝfrmOptionsªí³æ¤¤ªº®Ø¬[(Frame)§ïÅܤj¤p(Resize)®É¡A¦p¦ó­«·s±Æ¦C©Ò¥]§tªº±±¨î¶µ¡C¤]¥i¬Ý¨ì·íªí³æ§ïÅܤj¤p®É¡A¦p¦ó¤@¨Ö§ïÅܮج[ªº¤j¤p¡C±z¥i¥H«Ø¥ß«Ü¦h¹³frmOptionsªº°Ñ¼Æ¤Æªí³æ¡A¨Ò¦p«Ø¥ß¨ã¦³«Ü¦hºØ«ö¶s¡B¹Ï¥Ü¡B¦r«¬ªº°T®§¤è¶ô¡C°Ñ¼Æ¤Æªºªí³æ³Ì¤jªº¦n³B¦b©ó¨ä¥i¥H­«½Æ¨Ï¥Î©Ê¡AÁa¨ÏÅã¥Ü¥~Æ[¤£¦P¡A¦ý¨ä¨Ï¥Î¤èªk³£¬O¬Û¦Pªº¡C³oºØ§Þ¥©¥i¥H¸`¬ÙEXEÀɮתº¤j¤p¤Î°õ¦æ®É©Ò¶·ªº°O¾ÐÅé¡C

§âªí³æ·í§@ª«¥óÂsÄý¾¹
¡@

±z¥i¥H§âªí³æ§@¥t¤@ºØ¹B¥Î¡C°²¦p±zªºÀ³¥Îµ{¦¡¼sªx¨Ï¥Îª«¥ó¼Ò²Õ¨ÓÀx¦s¡B³B²z¸ê®Æ¡A±z¥i¯à»Ý­n¤@­Ó¯S®íªº¸ê®Æª«¥óÂsÄý¾¹¡CÁ|¨Ò¨Ó»¡¡A°²¦p±z¨Ï¥Î¤@­Ó¦W¬°Cpersonªºª«¥ó¼Ò²Õ¨Ó¦s©ñ­Ó¤H¸ê®Æ¡A±z¥i¥H«Ø¥ß¤@­ÓfrmPersonªí³æ¼Ò²Õ¡A¥¦¨ã¦³¤@­Ó«¬ºA¬°CpersonªºPersonÄÝ©Ê¡C³o¼Ë¥i¤j´T²¤Æ¥Î¤áºÝªºµ{¦¡¡A¦]¬°¥¦¥u­n«ü©w¤@­Óª«¥ó¡A¦Ó¤£»Ý«ü©w¦UºØ¤£¦PªºÄÝ©Ê (¦p¥»¨Ò¤¤ªº Name¡BAddress¡BCity¤ÎMarried )¡G

' The client code that uses the frmPerson form
Dim Person1 As New CPerson
' Initialize properties for this instance.
Person1.Name = "John Smith"
Person1.Address = "12345 West Road"
...
' Display it on screen.
Dim frm As New frmPerson
Set frm.Person = Person1
frm.Show

frmPersonªí³æ¥²¶·¥¿½Tªº§â Person ÄÝ©Ê«ü©wµ¹¹ïÀ³ªºÄæ¦ì¡A¦p¹Ï9-5¤Î¥H¤Uªºµ{¦¡½X¡C


¡@

¹Ï9-5 ¨Ï¥Îªí³æ¨Ó·í§@ª«¥óÂsÄý¾¹¡C³o¨â­Óªí³æ¹êÅéÅã¥Ü¦P¤@­ÓCpersonª«¥ó¡A¨Ã¥B·|¦Û°Ê¦P¨B¤Æ¡C
' Inside the frmPerson form module
Private WithEvents ThisPerson As CPerson

Property Get Person() As CPerson
    Set Person = ThisPerson
End Property
Property Set Person(newValue As CPerson)
    ' Initialize the private object and form fields.
    Set ThisPerson = newValue
    With ThisPerson
        txtName.Text = .Name
        txtAddress.Text = .Address
        txtCity.Text = .City
        chkMarried.Value = Abs(.Married)    ' Assign zero or one.
    End With
End Property

¨Ï¥Î³oºØ§Þ¥©¥t¤@­Ó¦n³B´N¬O¥Î¤áºÝªºµ{¦¡¤£·|ª½±µ¹ïCpersonª«¥óªºÄÝ©Ê°µ¦s¨ú¡C·íª«¥ó¼Ò²Õªº¤¶­±§ïÅܮɡA±z¥²¶·¦bfrmPerson¼Ò²Õ·s¼W©Î²¾°£³¯­z¦¡(statements)¡A¦ý¬O¤£»Ý­n­×§ï¥Î¤áºÝªºµ{¦¡.¡C

§ó§®ªº¦n³B¬O¡G·íªí³æª½±µ»Pª«¥ó³sµ²®É¡Aªí³æ¥i¥H¨ú¥Nª«¥ó¥»¨­¹ï¸ê®ÆªºÅçÃÒ¤u§@¡A¦b³]­pª«¥ó¾É¦VªºÀ³¥Îµ{¦¡¤¤¡A³o¬O¥¿½TªºÆ[©À¡CÅçÃÒªº¤u§@³q±`µo¥Í¦b¨Ï¥ÎªÌ«ö¤UOK«ö¶s®É¡G

' In the frmPerson form module...
Private Sub cmdOK_Click()
    On Error Resume Next
    ' Assign (and implicitly validate) the Name property.
    ThisPerson.Name = txtName.Text
    If Err Then
        ' If the class raised an error
        MsgBox Err.Description
        txtName.SetFocus
        Exit Sub
    End If

    ' Similar code for the Address, City, and Married properties.
    ...
End Sub

¨Ï¥Îªí³æ¨ÓÂsÄýª«¥óÁÙ¦³²Ä¥|ÂI¦n³B¡A¦bµ§ªÌ¬Ý¨Ó¬O³Ì­«­n¥B³Ì¨ã¦³§Þ³Nªº¤@ÂI¡C¬JµM¨C­Óªí³æ³£¦³¤@­Ó¹ïª«¥óªº¤Þ¥Î¡A§Ú­Ì¥i¥H²£¥Í¦h­Óªí³æ«ü¦V¦P¤@­Óª«¥ó¡CÁöµM¨C­Óªí³æ¦s¨ú¬Û¦Pªº¸ê®Æ¡A«o¯à©óÅã¥Ü®É¨ã³Æ¤@­P©Ê¡C½Ð°õ¦æObjView.Vbp±M®×¡A´N¥iÁA¸Ñµ§ªÌ©Ò­nªí¹Fªº¡C¦bJohn Smith«ö¶s«ö¤U¨â¦¸¥H¤W¡A¨Ã§ó§ïªí³æ¤¤ªº¸ê®Æ¡A¦AÂI¿ïOK«ö¶s¡A¥iµo²{¨ä¥¦ªºªí³æ¤¤ªº­È¤]³Q¦Û°Êªº§ó·s¡CÂǥѦb¥Dªí³æ¤¤Notification frame¿ï¾Ü¤£¦Pªº¿ï¶µ¡A±z¤]¥i¥H³]©w¦b¨Ï¥ÎªÌÂ÷¶}Äæ¦ì¬Æ¦Ü¨C«ö¤U¤@­ÓÁä®É¡A§ó·s¨ä¥¦ªí³æ¤Wªº­È¡C¦b½d¨Òµ{¦¡¤¤¡Aµ§ªÌ¼W¥[³o¨Ç¥\¯à¥u¬O¬°¤FÃÒ©ú³o¨Ç¥\¯à¥i¥H³Q¹ê§@¡C

­n¹ê§@²Ä¥|ÂI¡A·íCpersonª«¥óªºÄݩʳQ§ó§ï®É¡A­n¤Þµo¤@­Ó¨Æ¥ó¡G

' In the CPerson class module...
Event Change(PropertyName As String)
' A private variable that holds the value of the Name property
Private m_Name As String

Property Let Name(newValue As String)
    ' It's very important that the new value always be checked.
    If newValue = "" Then Err.Raise 5, , "Invalid Value for Name property"
    If m_Name <> newValue Then
        m_Name = newValue
        PropertyChanged "Name"
    End If
End Property

' Similar code for Property Let Address/City/Married
... 

' This private method simply raises a Change event in client code.
Private Sub PropertyChanged(PropertyName As String)
    RaiseEvent Change(PropertyName)
End Sub

¦bfrmPersonªí³æ¼Ò²Õ¤¤¡AThisPerson Åܼƫü¨ìCpersonª«¥ó¡A¥B¨Ï¥ÎWithEvent ÃöÁä¦r¡A¦]¦¹¥i¥H®·®»Cpersonªº Change ¨Æ¥ó¡G

Private Sub ThisPerson_Change(PropertyName As String)
    Select Case PropertyName
        Case "Name"
            txtName.Text = ThisPerson.Name
        Case "Address"
            txtAddress.Text = ThisPerson.Address
        Case "City"
            txtCity.Text = ThisPerson.City
        Case "Married"
            chkMarried.Value = Abs(ThisPerson.Married)
    End Select
End Sub

·í§âªí³æ·í§@ª«¥óÂsÄý¾¹¨Ó¨Ï¥Î®É¡A¦³¨âÂI¥²¶·ª`·Nªº¡G

  • ¦b±zªºÀ³¥Îµ{¦¡¤¤¡A¥i¥H¦³¤£¦PÃþ§Oªºªí³æ«ü¨ì¦P¤@­Óª«¥ó¡C¨Ò¦p¡AfrmPersonªí³æ¥i¥HÅã¥Ü¦³Ãöperson°ò¥»ªº¸ê°T¡A¦ÓfrmPerson«h°£¤FÅã¥Ü°ò¥»¸ê°T¥~¡AÁÙ¦³¤@¨Ç«O±K©Êªº¸ê°T¡A±z¥i¥H¦P®É¨Ï¥Î³o¨âºØªí³æ¡A¨Ó«ü¦V¦P¤@­Óª«¥ó¡C³o¼Ëªº§@ªk¥i¤j´T´î¤Öµ{¦¡½X¡A¦]¬°ÅçÃÒ¸ê®ÆªºÅÞ¿è¥i¥H¼g¨ìª«¥ó¼Ò²Õ¤¤¡A¦Ó¤£¥Î¦b¨C­ÓÃþ§Oªí³æ¤¤³£¼g¬Û¦Pªºµ{¦¡½X¡C
    ¡@
  • ·íª«¥óÃþ§O´£¨Ñªº²Ä¤G²Õ³q¥Î¤¶­±(Common interface)¡A±z¤]¥i¥H±N¬Û¦Pªºªí³æ¼Ò²Õ¨Ó®M¥Î¦b¤£¦Pªºª«¥óÃþ§O¤W¡CÁ|¨Ò¨Ó»¡¡A±z¥i¥H±NÀ³¥Îµ{¦¡¥Î¦bCperson¡BCcustomer¡BCemployeeª«¥ó¤W¡A¥u­n¥¦­Ìimplement IpersonalData¤¶­±¡C¥¦¥Nªí¤W­zª«¥ó¦@¦PªºÄÝ©Ê¡A±z¥i¥H«Ø¥ßfrmPersonalDataªí³æ¼Ò²Õ¨Ó¨Ï¥Î PersonalData ÄÝ©Ê¡G
    ¡@
' Inside the frmPersonalData form module...
Private PersData As IPersonalData

Property Get PersonalData() As IPersonalData
    Set PersonalData = PersData
End Property

Property Set PersonalData(newValue As IPersonalData)
    Set PersData = newValue
    ' Initialize fields on the form.

    With PersData

        txtName = .Name

        ...

    End With
End Property

¦P¼Ëªº¡A±z¤£¯à³z¹L²Ä¤GºØ¤¶­±¨Ó®·®»³o¨Çª«¥óªº¨Æ¥ó¡A©Ò¥H¡A¥u¦³±z¤£»Ý­nÅýªí³æ¤Wªº¸ê®Æ¦Û°Ê¦P¨B§ó·s®É¡A¤~¥i¨Ï¥Î³o­Ó§@ªk¡C

¦ý·í±z¨Ï¥Î±j¨î¦^À³¦¡(modal)ªí³æ®É¡A´N¤£¥ÎÅU¼{¨ì¸ê®Æ¦P¨Bªº°ÝÃD¤F¡C

°ÊºA·s¼W±±¨î¶µ
¡@

¦bVisual Basic 6¤¤·s¼W¥[ªº°ÊºA·s¼W±±¨î¶µ¥\¯à¡A¬O¥O¤j®a«Ü´Á«Ýªº¡A¦]¬°¦b¤§«eªºª©¥»¡Aµ{¦¡¦]¬°¤£¨ã³o¶µ¥\¯à¦Ó¨ü¨ì«Ü¤jªº­­¨î¡C³o¶µ¥\¯à¥i¥HÅý±z¦b°õ¦æ®É´Á¨Ï¥ÎÃþ§O¦WºÙ(Class name)¨Ó·s¼W±±¨î¶µ¡C³o­Ó¾÷¨î¤ñ¨Ï¥Î±±¨î¶µ°}¦C(control array)ÁÙ¨ã¼u©Ê(½Ð°Ñ¦Ò ²Ä¤T³¹ )¡A¨Æ¹ê¤W¡A¨Ï¥Î±±¨î¶µ°}¦C®É¡A±j­¢±z¦b³]­p®É´Á´N¥²»Ý¥ý©ñ¤W±z­n°ÊºA¼W¥[±±¨î¶µªº¹êÅé¡A¬Û¤Ï¦a¡A³z¹LVisual Basic 6¤¤°ÊºA·s¼W±±¨î¶µ¥\¯à´N¤£»Ý³o­Ó°Ê§@¡C

±±¨î¶µ¶°¦X(Controls collection)ªºAdd¤èªk
¡@

¦bVisual Basic6¤¤¡A±±¨î¶µ¶°¦X´£¨Ñ Add ¤èªk¥i¥HÅý±z¦b°õ¦æ®É´Á°ÊºA·s¼W±±¨î¶µ¡A©³¤U¬O Add ¤èªkªº»yªk:

Set controlRef=Controls.Add(ProgID¡AName [,Container])

ProgID¬O«ü±±¨î¶µªºÃþ§O¦WºÙ¡A¥¦¬O Libraryname.controlname ªº®æ¦¡¡CName ¬O±zµ¹±±¨î¶µªº¦WºÙ¡A (³o´N¬O±±¨î¶µNameÄݩʩҶǦ^¦WºÙ) ¡CName ¥²»Ý¬°°ß¤@ªº(unique)¡A°²¦p¦b¶°¦X¤¤¦³¨ä¥¦ªº±±¨î¶µ¨ã¦³¦P¼Ëªº¦WºÙ¡A´N·|²£¥ÍError 727 "There is already a control with the name 'ctrlname'" ¡CContainer ¬°¿ï¾Ü©Ê°Ñ¼Æ¡A¬O¤@­Ó¹ï¦¬¯Ç¾¹±±¨î¶µ(¦pPictureBox ©Î¬OFrame±±¨î¶µ)ªº¤Þ¥Î¡A¦pªG¨S¦³«ü©w©Î¬° NULL¡A¹w³]­È¬°Controls ¶°¦Xª«¥ó©ÒÄݪº¦¬¯Ç¾¹¡CControlRef ¬°ª«¥óÅܼơA¬O¤@­Ó¹ï¸Ó±±¨î¶µªº¤Þ¥Î¡A³z¹L¦¹Åܼƥi¨Ï¥Î±±¨î¶µªºÄÝ©Ê¡A¤èªk¤Î¨Æ¥ó¡A¥Ñ©³¤Uªºµ{¦¡½X±z¥i¥Hµo²{­n¦bªí³æ¥k¤U¨¤¡A°ÊºA·s¼W¤@­Ó CommandButton ±±¨î¶µ¡A¬O«D±`®e©öªº¤@¥ó¨Æ¡C

Dim WithEvents cmdCalendar As CommandButton

Private Sub Form_Load()
    Set cmdCalendar = Controls.Add("VB.CommandButton", "cmdButton")
    ' Assumes that form's ScaleMode is twips.
    cmdCalendar.Move ScaleWidth - 1400, ScaleHeight - 800, 1000, 600
    cmdCalendar.Caption = "&Calendar"
    ' All controls are created invisible.
    cmdCalendar.Visible = True
End Sub

¦b cmdCalendar ¤¤¨Ï¥Î¨ì WithEvents Åܼƥi¥HÅý±z¹ï¥¦ªº¨Æ¥ó§@³B²z¡A¨Ò¦p±z¥i¥H¦b¨Ï¥ÎªÌ«ö¤U°ÊºA·s¼Wªº«ö¶s®ÉÅã¥Ü¥X¤@­Ó¦Û­qªº¤é¾ä¡G

Private Sub cmdCalendar_Click()
    Dim frm As New frmCalendar
    frm.ShowMonth Year(Now), Month(Now)
    frm.Show vbModal
End Sub

±z¤]¥i¨Ï¥Î Remove ¤èªk¨Ó²¾°£¤w¸g°ÊºA¼W¥[ªº±±¨î¶µ¡A¥¦¥u¦³¤@­Ó°Ñ¼Æ¡G±±¨î¶µªº¦WºÙ¡A(´N¬O Add ¤èªkªº²Ä¤G­Ó°Ñ¼Æ):

Controls.Remove "cmdButton"

°²¦p±z¸Õ¹Ï²¾°£¤@­Ó¤£¬O¦b°õ¦æ®É´Á°ÊºA·s¼Wªº±±¨î¶µ¡A±N·|µo¥Í¿ù»~¡C

°ÊºA·s¼W¥~³¡ªºActiveX ±±¨î¶µ
¡@

·s¼W¥~³¡ActiveX ±±¨î¶µ¤è¦¡¸ò·s¼WVisual Basic¤º«Ø±±¨î¶µ¦³ÂI¹³¡A

¦ý¬O¦³¨âÂI²Ó¸`±z¥²»Ýª`·N¡G


»¡©ú

±z¥i¥H°ÊºA·s¼W°£¤FMenu Items¥H¥~©Ò¦³Visual Basic¤º«Øªº±±¨î¶µ¡A¤£©¯ªº¬O¡A³o­Ó­­¨îÅýµ{¦¡³]­p®v¦b°õ¦æ®É´ÁµLªk°ÊºA§ó§ï¿ï³æµ²ºc¡C


«Dµøµ¡±±¨î¶µµ{¦¡®w
¡@

Visual Basic 6·s¼W¥[¤F¤@­Ó«Dµøµ¡±±¨î¶µµ{¦¡®w¡A³o¨Ç±±¨î¶µ¤£½×¥~Æ[¤Î¯S©Ê´X¥G³£¸òVisual Basic¤º«Øªº±±¨î¶µ¨S¨â¼Ë¡CVisual Basic¤å¥ó¥»¨­¨Ã¨S¦³´£¨ì³o­Óµ{¦¡®w¡A¦]¦¹±z¥²»Ý¦Û¤v¥ÑCommon\Tools\Visual Basic\Winless ¥Ø¿ý¤¤¨Ó¦w¸Ë¡C³o­Ó¥Ø¿ý¥]§t¤@­Ó Mswless.ocx ActionX±±¨î¶µ¡A¥H¤Î¤@¥÷ÀɦW¬°Ltwtct98.chm ªº»¡©ú¤å¥ó¡C­n¨Ï¥Î³o­Óµ{¦¡®w¡A±z¥²»Ý¥ý±N¸Ó¥Ø¿ý½Æ»s¨ìµwºÐùØ¡A¨Ï¥Î¤§«e±z¥²¶·§Q¥ÎRegsvr32.exe ¨Ó±N¥¦µù¥U¨ì¨t²Î¡A©Î¬O¦bVisual Basic¤¤double-click Mswless.regÀɮסA³o·|²£¥Í¯àÅýVisual BasicÀô¹Ò¡A¨Ï¥Î³o­Ó±±¨î¶µªº¾÷½X¡C

¤@¥¹±z§¹¦¨µù¥Uµ{§Ç¡A±z«K¥i¦bµo®iÀô¹Ò¤U«ö Ctrl+T Áä¡A¿ï¨úMicrosoft Windowless Controls 6 ¶µ¥Ø¡AµM«á±z·|µo²{¤u¨ã½c¤¤¤S¦h¤F´X­Ó±±¨î¶µ

³o­Óµ{¦¡®w´£¨Ñ¤FTextBox¡BFrame¡BCommandButton¡BCheckBox¡BOptionButton¡BComboBox¡BListBox¡A¥H¤Î¨â­Ó ScrollBarªº±±¨î¶µ¡A¥¦¨Ã¥¼´£¨ÑLabel¡BTimer¡B©ÎImage±±¨î¶µ¡A¦]¬°¦bVisual Basic¥»¨­¤¤¡A³o¨Ç±±¨î¶µ¥»¨Ó´N¬O«Dµøµ¡(windowless)ªº¡C¥t¥~¥¦¤]¥¼¥]§tPictureBox ¤ÎOLE ±±¨î¶µ¡A³o¬O¦]¬°³o¨âªÌ¬O¦¬¯Ç¾¹¡A¦]¦¹¤£·|¦³«Dµøµ¡ªºª©¥»¡C«Dµøµ¡ªº±±¨î¶µ¤£´£¨Ñ hWnd ÄÝ©Ê¡A½Ð¦^¾Ð¦b ²Ä¤G³¹ ©Ò´£¤Îªº hWnd ÄÝ©Ê¡A³o­ÓÄݩʬOÅýWindowÃѧO±±¨î¶µ¥Îªº¡A¬JµM«Dµøµ¡±±¨î¶µ¡A¨ºhWnd ´N¨S¦³·N¸q¤F¡A ¥t¥~¥¦¤]¬Ù²¤¤F¤@¨Ç¥Î¨Ó¦bDDE·¾³q¥ÎªºÄÝ©Ê(DDE §Þ³N¤w¸g¹L®É¤F¡A¥»®Ñ±N¤£±´°Q) ¡C¥t¥~¤@­Ó¤£¦PÂI¬O¡A¦b«Dµøµ¡ªºWLOption ±±¨î¶µ(»PVisual Basic¤º«ØªºOptionButton¬Û¹ïÀ³)¤¤¡A´£¨Ñ·sªº Group ÄÝ©Ê¡A¥i¥H¦bªí³æ¤¤¦Û­q´X­Ó¤£¦P¸s²Õ¡AÅý¦b¬Û¦P¸s²Õ¤ºªº Radio «ö¶s¤¬¥¸ (±z¤£¥i¥H§Q¥Î±NRaio«ö¶s©ñ¦b WLFrame¤W¨Ó¹F¨ì¤¬¥¸¡A¦]¬°WLFrame ±±¨î¶µ¤£¬O¤@­Ó¦¬¯Ç¾¹) ¡C

°£¤F hWnd ¤Î Group ÄÝ©Ê¥~¡A¦b³o­Óµ{¦¡®w¤¤ªº±±¨î¶µ³£§¹¬ü¦a»PVisual Basic¤º«Øªº±±¨î¶µ¬Û®e¡A¦³¦P¼ËªºÄÝ©Ê¡B¤èªk¡B¨Æ¥ó¡C¦³½ì¦a¬O¡A³o­Óµ{¦¡®w¤¤ªº±±¨î¶µ³£´£¨ÑÄÝ©Ê­¶(property page) ¡AÅýµ{¦¡³]­p®v§ó»´ÃPªº³]©w¨C­Ó±±¨î¶µªºÄÝ©Ê¡A¦p¹Ï9-8¡C


¡@

¹Ï9-8 ±z¥i¥H¨Ï¥ÎÄÝ©Ê­¶¨Ó³]©w¦b«Dµøµ¡µ{¦¡®w¤¤ªº±±¨î¶µ¡A½Ðª`·N¥X²{¦b¤u¨ã½cªº·s±±¨î¶µ¡C

¨Ï¥Î«Dµøµ¡±±¨î¶µªº¦n³B¬O¦b°õ¦æ®É¤£¥Î¹³Visual Basic¤º«Ø±±¨î¶µ¤@¼Ë¨ü¨ì³\¦h­­¨î¡C¨Æ¹ê¤W«Dµøµ¡±±¨î¶µ©Ò¦³ªºÄݩʳ£¥i¦b°õ¦æ®É´Á§ó§ï¡A¦pWLText±±¨î¶µªº Multiline ¤Î ScrollBars ÄÝ©Ê¡BWLList¤ÎWLCombo±±¨î¶µªºSorted¤Î Style ÄÝ©Ê¡BWLCheck¤ÎWLOption±±¨î¶µªº Alignment ÄÝ©Ê¡C

³oºØ¥i¦b°õ¦æ®É´Á³]©wÄݩʪº¯à¤O¡A¦b°ÊºA·s¼W±±¨î¶µ®É«D±`­«­n(¨Ï¥ÎControls.Add ¤èªk)¡A·í±z°ÊºA·s¼W±±¨î¶µ¡A¥¦­ÌªºÄÝ©Ê·|³Q³]©w¬°¤º©w(default) ­È¡A³o¥Nªí·í±z­n°ÊºA·s¼WVisual Basic¤º«Øªº±±¨î¶µ¡A¦pTextBox¡A±z¤£¯à§ïÅÜ multiline ÄÝ©Ê¡A©Î¬O§ó§ïListBox¡BComboBoxªº Sort ÄÝ©Ê¡A¬Û¹ï¦a¡A³o¥u¦³»´¶q±±¨î¶µ¯à¹F¨ì¡G

Dim WithEvents TxtEditor As MSWLess.WLText

Private Sub Form_Load()
    Set TxtEditor = Controls.Add("MSWLess.WLText", "txtEditor")
    TxtEditor.MultiLine = True
    TxtEditor.ScrollBars = vbBoth
    TxtEditor.Move 0, 0, ScaleWidth, ScaleHeight
    TxtEditor.Visible = True
End Sub

¥¼¤Þ¥Îªº±±¨î¶µ
¡@

¨ì¥Ø«e¬°¤î¡Aµ§ªÌ©ÒÁ¿ªº³£¬O¨º¨Ç³]­p®É´Á´N¤w¸g¦b¤u¨ã½c¤Þ¥Îªº±±¨î¶µ¡A¦ý³z¹L«Ø¥ß°ÊºA±±¨î¶µ¯SÂI¡A«Ø¥ß¥¼³Q¤u¨ã½c¤Þ¥ÎªºActiveX±±¨î¶µ¡A±z¥i¥Hµo´§§ó¤jªº¥\¯à¡C

±z¥i¥H³]­p¥X¤ä´©¤£¦Pª©¥»ActiveX±±¨î¶µªºÀ³¥Îµ{¦¡¡A¨Ò¦p·í·sªº±±¨î¶µµo§G®É¡A¥u­n§ó§ï¦s¦bINIÀÉ®×ùر±¨î¶µªº¦WºÙ´N¥i¥H¤F¡C·í±z­n§âªí³æÂনActiveX ±±¨î¶µ¦¬¯Ç¾¹¡A³o­Ó¥\¯à´£¨Ñ§ó¤jªº¼u©Ê¡C

­º¥ý¡A±z¥²¶·¸Ñ¨M¨º¨Ç¦b³]­p®É´Á¥¼¥X²{¦b¤u¨ã½cªº±±¨î¶µ±ÂÅv°ÝÃD¡C§Y¨Ï±z¹ê»Ú¤W¨S¦b³]­p®É´Á¨Ï¥Î¨ì¸Ó±±¨î¶µ¡A±z¤´¥²¶·ÃÒ©ú¦b°õ¦æ®É´Á°ÊºA¸ü¤J¸Ó±±¨î¶µ¬O¦Xªkªº¡C¦pªG¦b°õ¦æ®É´Á¡A¹ï°ÊºA¸ü¤JActiveX±±¨î¶µ¨S°µ¥ô¦ó­­¨î¡A¨º¥ô¦ó¤@­Óµ{¦¡³]­p®v³£¥i¥H¥ô·N¦V°Ó·~³nÅé¡u­É¡vActiveX ±±¨î¶µ¨Ó¨Ï¥Î¡A¦Ó¤£¥Îªá¿ú¥hÁʶR±ÂÅv¡C³o­Ó°ÝÃD¥u¥X²{¦b°õ¦æ®É´Á¥¼¤Þ¥Î¦b¤u¨ã½cªº±±¨î¶µ¤W¡A­Y±z¥i¥H§â±±¨î¶µ¸ü¤J¨ì¤u¨ã½c¡A¨º±z´N¨ã¦³¤F³]­p®É´Áªº±ÂÅv¡C

­n¦b°õ¦æ®É´Á°ÊºA·s¼W¤@­Ó¥¼¤Þ¥Î¦b¤u¨ã½cªºActiveX±±¨î¶µ¡A¦b½sĶ®É±z¥²¶·´£¥X±zªº³]­p®É´Á±ÂÅv¡C³oùتº±ÂÅv¬O«ü·í±z¦b¾÷¾¹¤W¦w¸Ë±±¨î¶µ®É¡A¦b¨t²ÎRegistry¤¤²£¥Í¤@­Ó¥Ñ¤å¦r¤Î¼Æ¦r²Õ¦X¦Ó¦¨ªº¦r¦ê¡CVisual Basic¤£±j­¢±z¤@©w­n¦bRegistry·j´M³o­Ó¦r¦ê¡A¦]¬°±z¥i¥H³z¹LLicenses ¶°¦Xª«¥óªºAdd¤èªk¨Ó¹F¦¨¡G

' This statement works only if the MSWLess library is
' *NOT* currently referenced in the Toolbox.
Dim licenseKey As String
licenseKey = Licenses.Add("MSWLess.WLText")

·í±z¨ú±o±ÂÅv¸ê®Æ(license string)¡A±z¥²¶··Q¥X¤@­Ó¤èªkÅý°õ¦æ®É´Á¥i¥H¨Ï¥Î¡A³Ì²³æªº¤è¦¡´N¬O§â¥¦¦s©ñ¦bÀɮפ¤¡G

Open "MSWLess.lic" For Output As #1
Print #1, licenseKey
Close #1

¤§«eªºµ{¦¡½X¥u¦³¦b³]­p¹Lµ{·|¨Ï¥Î¨ì¡A¤@¥¹²£¥Í¤FLICÀɮסA±z´N¤£·|¦A¨Ï¥Î¨ì¤F¡CÀ³¥Îµ{¦¡°õ¦æ®É·|§Q¥ÎLicenses ¶°¦Xª«¥ó¥t¤@­Ó¤£¦P»yªkªº Add ¤èªk¡G

Open "MSWLess.lic" For Input As #1
Line Input #1, licenseKey
Close #1
Licenses.Add "MSWLess.WLText", licenseKey

Licenses¶°¦Xª«¥ó¤]´£¨Ñ Remove ¤èªk¡A¦ý±zÀ³¸Ó¤£·|¨Ï¥Î¨ì¥¦¡C

«á´Á³sµ²ªºÄÝ©Ê¡B¤èªk¤Î¨Æ¥ó
¡@

·í±z¸Ñ¨M¤F±ÂÅvªº°ÝÃD¡A±µ¤U¨Ó±z¥²¶·­±¹ï½sĶ¥¼³Q¤Þ¥Î¦b¤u¨ã½cªºActiveX±±¨î¶µ·|²£¥Íªº°ÝÃD¡C¥¿¦p±z·Q¹³ªº¡A°²¨Ï±z¤£ª¾¹D¦b°õ¦æ®É´Á·|¸ü¤J­þ­Ó±±¨î¶µ¡A´NµLªk«ü©w¥¿½T«¬ºAµ¹ Controls.Add ¤èªk©Ò¶Ç¦^ªºÅܼơC³o·N«ü±z¨S¦³Â²³æªº¤èªk¥h¦s¨ú·s¼W±±¨î¶µªºÄÝ©Ê¡B¤èªk¤Î¨Æ¥ó¡C

Visual Basic 6©Ò´£¨Ñªº¸Ñ¨M¿ìªk¬O¤@­Ó¯S§Oªºª«¥óÅÜ¼Æ vbControlExtender¡A³o¬O¤@­ÓVisual Basic¾ã¦Xµo®iÀô¹ÒªºActiveX±±¨î¶µ¡G

Dim WithEvents TxtEditor As VBControlExtender

Private Sub Form_Load()
    ' Add the license key to the Licenses collection (omitted).
    Set TxtEditor = Controls.Add("MSWLess.WLText", "TxtEditor")
    TxtEditor.Move 0, 0, ScaleWidth, ScaleHeight
    TxtEditor.Visible = True
    TxtEditor.Text = " My Text Editor"
End Sub

­n®·®»¥¼³Q¤Þ¥Î¦b¤u¨ã½cªºActiveX±±¨î¶µªº¨Æ¥ó¡A¤ñ¦s¨ú¥¦ªºÄݩʩΤèªk­n¨ÓªºÃø¡CvbControlExtender¨Ã¤£·|§â·s±±¨î¶µªº¨Æ¥ó´£¨Ñµ¹¨Ï¥ÎªÌ¡A¬Û¤Ïªº¡A¥¦¥u¦³¤@­Ó¦W¬° ObjectEvent ªº¨Æ¥ó¡A³o­Ó¨Æ¥óªº§@¥Î¡A¬O¹ï°ÊºA·s¼Wªº±±¨î¶µ©Òµo¥X¤§©Ò¦³¨Æ¥ó¶i¦æ¸ÑªR¡CObjectEvent ±µ¦¬¤@­Ó°Ñ¼Æ¡A¤@­Ó¥]§tEventParameterª«¥ó¶°¦XªºEventInfoª«¥ó¡C³o­Ó¶°¦X¥iÅýµ{¦¡³]­p®v¨ú±o¶Ç»¼µ¹¨Æ¥óªº°Ñ¼Æ¡C


¡@

³q±`§Ú­Ì·|¦b ObjectEvent ¨Æ¥óµ{§Ç¤¤¡AÀˬd EventInfo.Name ÄݩʨӿìÃѬO­þ¤@­Ó¨Æ¥ó³QIJµo¡A§Ú­Ì¤]¥i¥HŪ¨ú¡A¬Æ¦Ü§ó§ï©Ò¶Ç¤Jªº°Ñ¼Æ¡G

Private Sub TxtEditor_ObjectEvent(Info As EventInfo)
    Select Case Info.Name
        Case "KeyPress"
            ' The Escape key clears the editor.
            If Info.EventParameters("KeyAscii") = 27 Then
                TxtEditor.Object.Text = ""
            End If
        Case "DblClick"
            ' Just to prove that we can trap any event
            MsgBox isWhy have you double-clicked me?"
    End Select
End Sub

¥Î³oºØ¨Æ¥ó®·®»¤è¦¡¡Aµ§ªÌºÙ¤§¬°«á´Á³sµ²ªº¨Æ¥ó¡C¬Y¨Ç©µ¦ù¨Æ¥ó(extender events)±z¤£·|¨Ï¥Î ObjectEvent ¨Æ¥ó¨Ó®·®»¡C³o¨Ç©µ¦ù¨Æ¥ó(¤U­±ªºµ{¦¡¤ù¬q«K¬O¤@¨Ò)¥i·í§@¬OvbControlExtenderª«¥óªº¼Ð·Ç¨Æ¥ó¡C³o²Õ¨Æ¥ó¥]§t GotFocus¡BLostFocus¡BValidate¡BDragDrop ¤Î DragOver¡C­n¶i¤@¨BÁA¸Ñ©µ¦ù¨Æ¥ó¡A½Ð°Ñ¾\ ²Ä17³¹ ¡C

Private Sub TxtEditor_GotFocus()
    ' Highlight textbox's contents on entry.
    TxtEditor.Object.SelStart = 0
    TxtEditor.Object.SelLength = 9999
End Sub

¸ê®Æ¾É¦V(Data-Driven)ªºªí³æ
¡@

°ÊºA·s¼Wª«¥óªº¥\¯àÅýVisual Basic 6¥i¥H«Ø¥ß¯u¥¿ªº¸ê®Æ¾É¦Vªí³æ¡C³oºØªí³æ·|¦b°õ¦æ®É´ÁÀHµÛ±qÀÉ®×Ū¶iªº¸ê®Æ©Î¬O¸ê®Æ®wªºµ²ºc¨Ó°ÊºA§ó§ï¦Û¤vªºÅã¥Ü¥~Æ[¡C·Q¬Ý¬Ý­Y§Ú­Ì¤£»Ý¦A­«·s½sĶµ{¦¡·|±aµ¹§Ú­Ì¦h¤jªº¤è«K¡G

  • ±z¥i¥Hª½±µ¦b¸ê®Æ®w¼W´îÄæ¦ì¡A¦Óªí³æ·|¦Û°Ê¼W´î±±¨î¶µ¨Ó¹ïÀ³¨ìÄæ¦ì¡C
    ¡@
  • ±z¥i¥H´£¨ÑÅý¨Ï¥ÎªÌ¦Û­qªí³æªºÃC¦â¡B¦r«¬¡BÄæ¦ì¦ì¸m¤Î¤j¤pµ¥ªº¥\¯à¡C
    ¡@
  • ±z¥i¨Ì¾Ú¤£¦P¨Ï¥ÎªÌªºµn¤J¡A¨Ó¨M©w­n¤£­nÅýÄæ¦ìÁôÂéάO°ßŪ¡C¨Ò¦p±z¥i¥H¥uÅý¤w±ÂÅvªº¨Ï¥ÎªÌ¨Ó¦s¨ú¾÷±Kªº¸ê°T¡A¨ä¥¦¤H«o¬Ý¤£¨ì¡C
    ¡@

­n¹ê§@¸ê®Æ¾É¦Vªºªí³æ¡A§Ú­Ì¥²¶·¥ý¸Ñ¨M¤@­Ó°ÝÃD¡C¬JµM§Ú­Ì¤£ª¾¹D·|¦³¦h¤Ö±±¨î¶µ·|³Q°ÊºA¥[¤J¨ìªí³æ¡A­n«ç»ò¥h®·®»¥¦­Ìªº¨Æ¥ó©O?·|¦³³o­Ó°ÝÃD¬O¦]¬° WithEvents ÃöÁä¦rµLªk®·®»¨ìª«¥ó°}¦Cªº¨Æ¥ó¡C¤U­±¡A±z±N·|µo²{³o­Ó°ÝÃDÁöµM¥i¥H³Q¸Ñ¨M¡A¦ý¨Ã¤£¦p·Q¹³¤¤ªºÂ²³æ¡CµM¦Ó¡Aµ§ªÌ±N±Ô­zªº³o­Ó§Þ¥©¤£¦ý¦³½ì¥B¨ã¼u©Ê¡A¤£¥u¥i¥HÀ³¥Î¦b»s§@¸ê®Æ¾É¦Vªºªí³æ¡A¤]¥i¥H¥Î¨Ó®·®»¥¼ª¾¼Æ¥Øªº±±¨î¶µ¨Æ¥ó¡A³o¥¿¬Oµ§ªÌ¦b²Ä¤C³¹©Ò¯d¤Uªº°ÝÃD¡C

®·®»±±¨î¶µ°}¦Cªº¨Æ¥ó
¡@

­n¦b°õ¦æ®É´Á®·®»¥¼©w¼Æ¥Øªº°ÊºA«Ø¥ß±±¨î¶µ©Î¬Oª«¥ó¡A±z¥²¶·¥ý«Ø¥ß¨â­Ó¤ä´©ªºÃþ§O¡A²Ä¤@­ÓÃþ§O¬O¶°¦XÃþ§O¡A¥]§t©Ò¦³²Ä¤G­ÓÃþ§Oªº¹êÅé¡C¦bÀH®Ñ¥úºÐªº½d¨Òµ{¦¡¤¤¡A³o¨â­ÓÃþ§O¦WºÙ¤À§O¬° ControlItems¤Î ControlItem¡C


¡@

¹Ï9-9 ±z»Ý­n¨â­Ó»²§UªºÃþ§O¥H¤Î¤@¨Ç¥©§®ªºµ{¦¡¨Ó®·®»°ÊºA«Ø¥ß±±¨î¶µ°}¦Cªº¨Æ¥ó¡C

©³¤U¬O®·®»¨Æ¥óªº¨BÆJ¡G

  1. ¥Dµ{¦¡¦³¤@­Ó CtrlArray ªºÅܼƨӤޥΨì ControlItems¶°¦XÃþ§Oªº¹êÅé¡A¥¦·|²£¥Í¨Æ¥ó¡A¦]¦¹ÅܼƳQ«Å§i¬° WithEvents¡C
  2. ·íªí³æ·s¼W¤@­Ó±±¨î¶µ¡Aªí³æ·|§Q¥ÎControlItems¶°¦XÃþ§Oªº Add ¤èªk¡A§â¹ï±±¨î¶µªº¤Þ¥ÎÀx¦s¦bControlItems ¶°¦XÃþ§O¡C³o­Ó¤Þ¥Î¥i¥H¬O¤@­Ó«ü©wªºÃþ§O(°²¨Ï¦b³]­p®É´Á¤w¸gª¾¹D­n·s¼W­þ¤@ºØ±±¨î¶µ)¡A°²¨Ï±z­n¨Ï¥Î«á´Á³sµ²ªº¨Æ¥ó¡A¥¦¤]¥i¥H¬OvbControlenderª«¥ó¡C
  3. ControlItems ¶°¦XÃþ§Oªº Add ¤èªk¡A·|«Ø¥ß¤@­Ó·sªºControlItemÃþ§O¹êÅé¡A¨Ã¥B¶Çµ¹·s¼W±±¨î¶µªº¤Þ¥Î¤Î¦Û¤vªº¤Þ¥Î¡C
  4. ControlItemÃþ§O¹êÅé¨Ï¥ÎPublicªº WithEvent ÅܼƨÓÀx¦s±±¨î¶µªº¤Þ¥Î¡A¤]¨Ï¥ÎPrivate ªº Parent ª«¥óÅܼƨӦs©ñControlItems ¶°¦XÃþ§Oªº¤Þ¥Î¡C
  5. ¦¹®É¡A·í±±¨î¶µ²£¥Í¤@­Ó¨Æ¥ó¡AControlItem·|¥ß¨è®·®»¨ì¡A¨Ã¥B¶Ç¦^µ¹ Parent ¶°¦XÃþ§O¡C°õ¦æ³qª¾ªº°Ê§@¬O§Q¥Î¤@­Ó¦bControlItems ¶°¦Xª«¥óªºFriendªº¤èªk¡A¤@¯ë¨Ó»¡±z¥²¶·¦bÃþ§O¤¤¡A´£¨Ñ³oºØ¤èªkµ¹¨C¤@­Ó­n®·®»ªº¨Æ¥ó¡A¦]¬°¨CºØ¨Æ¥ó¦³¤£¦Pªº°Ñ¼Æ¡C
  6. ¦bnotification ¨Æ¥ó¤¤¡AControlItems Ãþ§O¥i¥H²£¥Í¤÷ªí³æªº¨Æ¥ó¡A¨Æ¥ó²Ä¤@­Ó³Q¶Ç¤Jªº°Ñ¼Æ¬O²£¥Í¨Æ¥óªº±±¨î¶µ¤Þ¥Î¡A©Î¬O¤@­Ó®·®»¨ì³o­Ó¨Æ¥óªºControlItemª«¥ó¤Þ¥Î¡C

±z¥i¥H¬Ý¨ì¡A­nÄdºI¨Æ¥ó¬O­n¸g¹L«Üªøªº¨BÆJ¡C¦ý¬O±z²{¦b¤w¸g¾Ç·|³o¨Ç§Þ¥©¡A±N¨Ó¤]¥i¥Î¦b¨ä¥Lªº¥Î³~¡C

¸ê®Æ®w¾É¦V ¸ê®Æµn°O ªºªí³æ
¡@

¨Ï¥Î°ÊºA«Ø¥ß±±¨î¶µ®É¾÷¤§¤@¡A´N¬OÅýªí³æ¥i¥HÀH¸ê®Æ®wªí®æ©Î¬O¬d¸ß¡A¨Ó§ïÅܪí³æ¥~Æ[¡C³o¦b¼¶¼g¦ñÀH¤j¶q¬d¸ßªº¤j³W¼Ò°Ó·~³nÅé®É«D±`¦³¥Î¡A¦]¬°±z¤£·|·Q­n¬°¨C¤@­Ó¬d¸ß»s§@¤@­Ó±M¥Îªí³æ¡C³o­Ó§Þ³N·|¤j¶qÁYµuµo®i®É¶¡¡B´î¤ÖÀɮפj¤p©Ò¦ûªº°O¾ÐÅé¤Î¸ê·½¡C

¦bÀH®Ñ¥úºÐ¤¤¡A±z¥i¥H§ä¨ì¤@­Ó§¹¾ãªºÀ³¥Îµ{¦¡¡A¥Dªí³æ¥i®Ú¾Ú¥ÑSQL SELECT¬d¸ß©Ò¶Ç¦^ªº¸ê®Æ®wªí®æ¨Ó°ÊºA§ïÅÜÄæ¦ì¡A¦p¹Ï9-10¡C


¡@

¹Ï9-10 ©Ò¦³¦b³o­Óªí³æ¤Wªº±±¨î¶µ¡A³£¬O°õ¦æ®É´Á¨Ì¾ÚADO recordset°ÊºA²£¥Íªº¡A³o¤äµ{¦¡·|®Ú¾Ú¤£¦PªºÄæ¦ì«¬ºA¡A²£¥Í¤£¦Pªº±±¨î¶µ¡A¤]·|¹ïÄæ¦ì°µÅçÃÒªº¤u§@¡C
' The collection of controls added dynamically (module-level
' variable)
Dim WithEvents ControlItems As ControlItems

' This is the most interesting routine, which actually
' creates the controls and passes them to the ControlItems
' collection class.
Sub LoadControls(rs As ADODB.Recordset)
    Dim index As Long, fieldNum As Integer
    Dim field As ADODB.field
    Dim ctrl As Control, ctrlItem As ControlItem, ctrlType As String
    Dim Properties As Collection, CustomProperties As Collection
    Dim top As Single, propItem As Variant
    Dim items() As String	

    ' Start with a fresh ControlItems collection.
    Set ControlItems = New ControlItems
    ' Initial value for Top property
    top = 100

    ' Add controls corresponding to fields.
    ' This demo program supports only a few field types.

    For Each field In rs.Fields
        ctrlType = """
        Set Properties = New Collection
        Set CustomProperties = New Collection
        Select Case field.Type
            Case adBoolean
                ctrlType = "MSWLess.WLCheck"
                Properties.Add "Caption="
            Case adSmallInt   ' As Integer
                ctrlType = "MSWLess.WLText"
            Case adInteger    ' As Long
                ctrlType = "MSWLess.WLText"
                CustomProperties.Add "IsNumeric=-1"
                CustomProperties.Add "IsInteger=-1"
            Case adSingle, adDouble, adCurrency
                ctrlType = "MSWLess.WLText"
                CustomProperties.Add "Numeric=-1"
            Case adChar, adVarChar  ' As String
                ctrlType = "MSWLess.WLText"
                Properties.Add "Width=" & _
                    (field.DefinedSize * TextWidth("W"))
            Case adLongVarChar   ' (Memo field)
                ctrlType = "MSWLess.WLText"
                Properties.Add "Width=99999"   ' Very large width
                Properties.Add "Height=2000"
                Properties.Add "Multiline=-1"
                Properties.Add "ScrollBars=2"   'vbVertical
            Case adDate
                ctrlType = "MSWLess.WLText"
                Properties.Add "Width=1000"
                CustomProperties.Add iIiIsDate=-1"
            Case Else
                ' Ignore other field data types.
        End Select

        ' Do nothing if this field type is not supported (ctrlType="").
        If ctrlType <> i>"" Then
            fieldNum = fieldNum + 1
            ' Create the label control with database field name.
            Set ctrl = Controls.Add(" VB.Label", "Label". & fieldNum)
            ctrl.Move 50, top, 1800, 315
            ctrl.Caption = field.Name
            ctrl.UseMnemonic = False
            ctrl.BorderStyle = 1
            ctrl.Alignment = vbRightJustify
            ctrl.Visible = True
            ' Create the control, and move it to the correct position.


            Set ctrl = Controls.Add(ctrlType, "Field" & fieldNum)
            ctrl.Move 1900, top, 2000, 315

            ' If the field is not updatable, lock it. 
            If (field.Attributes And adFldUpdatable) = 0 Then
                On Error Resume Next
                ctrl.Locked = True
                ' If the control doesn't support the Locked property,
                ' disable it.
                If Err Then ctrl.Enabled = False
                On Error GoTo 0
            End If

            ' Set other properties of the field.
            For Each propItem In Properties
                ' Split property's name and value.
                items() = Split(propItem, "=")
                CallByName ctrl, items(0), VbLet, items(1)
            Next
             Link it to the Data control, and make it visible.
            Set ctrl.DataSource = Adodc1
            ctrl.DataField = field.Name
            ctrl.Visible = True
            ' Add this control to the ControlItems collection.
            Set ctrlItem = ControlItems.Add(ctrl)
            ' Move the actual width into the custom Width property.
            ' This is used in the Form_Resize event.
            ctrlItem.Properties.Add ctrl.Width, i|uWidth"
            ' Set its other custom properties.
            For Each propItem In CustomProperties
                ' Split property name and value.
                items() = Split(propItem, "=")
                ctrlItem.Properties.Add items(1), items(0)
            Next
            ' Increment top.
            top = top + ctrl.Height + 80
        End If
    Next
    ' Force a Form_Resize event to resize longer controls.
    Call Form_Resize
    Adodc1.Refresh
End Sub

' A control added dynamically is asking for validation.
' Item.Control is a reference to the control.
' Item.GetProperty(propname) returns a custom property.
Private Sub ControlItems_Validate(Item As ControlItem, _
    Cancel As Boolean)


    If Item.GetProperty("Numeric") Then
        If Not IsNumeric(Item.Control.Text) Then
            MsgBox "Please enter a valid number"
            Cancel = True: Exit Sub
        End If
    End If
    If Item.GetProperty("IsInteger") Then
        If CDbl(Item.Control.Text) <> Int(CDbl(Item.Control.Text)) Then
            MsgBox "Please enter a valid Integer number"
            Cancel = True: Exit Sub
        End If
    End If
    If Item.GetProperty("IsDate")) Then
        If Not IsDate(Item.Control.Text) Then
            MsgBox "Please enter a valid date"
            Cancel = True: Exit Sub
        End If
    End If
End Sub

«Ü¦h¦a¤è¥i¥H¬Ý¥X LoadControls ±`¦¡­È±o§Ú­Ì¦A¶i¤@¨Bªº±´°Q¡C­º¥ý¡A¬°¤F¯à¦b°õ¦æ®É§ó§ï¦pTextBox±±¨î¶µªº Multiline ÄÝ©Ê(¨Ò¦p¦bmemoÄæ¦ì®É)¡A¥¦¨Ï¥Î«Dµøµ¡±±¨î¶µ¡C¨ä¦¸¡A¬°¤FÅýµ{¦¡¬[ºc§ó¦³®Ä²v¥H¤Î§ó¨ã©µ®i©Ê¡A¦b¥D Select ±Ô­z¤¤ªº Case ¤l¥y¡A¥u¬O§âÄݩʦWºÙ¤Î­È¥[¤J¨ì Properties¶°¦X¤¤¡G·í±±¨î¶µ³Q«Ø¥ß®É¡A¦b For Each °j°é¤¤¡A¨Ï¥Î CallByName «ü¥O¨Ó«ü©w¨C­ÓÄÝ©Ê¡C²Ä¤T¡ALoadControls¤¤«Ø¥ß¤@­Ó CustomProperties ¶°¦X¨Ó¦s©ñ¨º¨Ç¤£¯à³Qª½±µ¦s¨úªº±±¨î¶µÄÝ©Ê¡A¥]§t¥Î¨ÓÅçÃҭȪº IsNumeric¡BIsInteger ¤Î IsDate ¦Û­qÄÝ©Ê¡C

½Ð°Ñ·ÓÀH®Ñ¥úºÐ¤¤ªº¥Dªí³æ¡AControlItems ¤Î ControlItem Ãþ§Oªº§¹¾ãµ{¦¡½X¡C

¦h­«¤å¥ó¤¶­±ªí³æ(MDI FORMS)
¡@

MDI¥Nªí¦h­«¤å¥ó¤¶­± (Multiple Document Inteface)¡A³o¬OMicrosoft Office ®M¸Ë³nÅ餤¡A³Ì±`¨Ï¥Îªº¨Ï¥ÎªÌ¤¶­±Ãþ«¬¡A¥]§t¤F Microsoft Word¡BMicrosoft Excel¤Î Microsoft PowerPoint¡C«Ü¦hÀ³¥Îµ{¦¡¤]¨Ï¥ÎMDI ¤¶­±¡A·í±zªºÀ³¥Îµ{¦¡¥²¶·¯à¦b¦P®É¶¡³B²z¦h­Ó¤å¥ó®É¡A¨º»ò¨Ï¥ÎMDI ¤¶­±·|¬O³Ì¦nªº¿ï¾Ü¡C

¦h­«¤å¥ó¤¶­±À³¥Îµ{¦¡
¡@

¥u­n±z¯à¥R¥÷µo´§Visual Basic´X­Ó¯S©Ê¡A­n¦bVisual Basic¤¤«Ø¥ßMDI¤¶­±¬O«D±`®e©öªº¡C­nµo®iMDIªºÀ³¥Îµ{¦¡¡A¥²¶·¦b±M®×¤¤·s¼W¤@­Ó MDIForm ¼Ò²Õ¡A°£¤F©³¤U´X­Ó¸û¯S®íªº©Ê½è¥~¡AMDIForm¼Ò²Õ´X¥G¸ò¤@¯ëªí³æ¨S¨â¼Ë¡G

  • ¨C­Ó±M®×¥u¯à¦³¤@­ÓMDIForm¼Ò²Õ¡A·í±z¦b±M®×¤¤·s¼W¤@­ÓMDI¼Ò²Õ«á¡AAdd MDIForm «ü¥O´N·|µL®Ä(disable)¡A¦b¥Dtoolbar¤¤ªº«ü¥O¤]¤@¼Ë¡C
    ¡@
  • ¤j¦h¼Æªº±±¨î¶µ¤£¯àª½±µ©ñ¦bMDIForm¤W¡A§ó©ú½Tªº»¡¡A±z¥u¯à©ñ¤u¨ã½c¤W¬Ý¤£¨£ªº±±¨î¶µ(¨Ò¦p Timer¤ÎCommonDialog±±¨î¶µ)¡A¥H¤Î¤ä´© Align Äݩʪº±±¨î¶µ(¨Ò¦p PictureBox¡BToolbar¤ÎStatusBar ±±¨î¶µ)¡A­nÅý¨C¤@ºØ±±¨î¶µ³£¯à©ñ¸m¨ìMDIFormª«¥ó¡A´N­n§â¥¦­Ì¥ý©ñ¨ì¤@­Ó¦¬¯Ç¾¹±±¨î¶µ¤¤¡A¦p¨å«¬ªºPuctureBox±±¨î¶µ¡C
    ¡@
  • ±z¤£¥i¥H¦bMDIForm¤WÅã¥Ü¤å¦r©Î¹Ï¤ù¡A¦P¼Ëªº¡A±z¥²¶·Âǥѩñ¸m¦b¤W­±ªºPictureBox¨Ó¹F¦¨¡C
    ¡@

¦h­«¤å¥ó¤¶­±¤lªí³æ
¡@

¤@­ÓMDIFormª«¥ó¥]§t¤@©Î¦h­Ó¤lªí³æ¡C­n«Ø¥ß³oºØ¤lªí³æ¡A¥u­n·s¼W¤@­Ó¤@¯ëªí³æ¡A¦A±N¥¦ªº MDIChild Äݩʳ]¬°True§Y¥i¡C·í±z°µ³o­Ó°Ê§@¡A±M®×Á`ºÞ¤ºªº¹Ï¥Ü¤]·|§ïÅÜ¡A¦p¹Ï9-11¡C§Ú­Ì¤£¥Î¥h³]©w¤lªí³æ¬OÁõÄÝ­þ­ÓMDIForm¡A¦]¬°¨C­Ó±M®×¥u·|¦³¤@­ÓMDIForm¼Ò²Õ¡C

MDI¤lªí³æ¤£¯àÅã¥Ü¦b¤÷MDIFormªº¥~­±¡A¥B·íMDI¤lªí³æ³Q³]©w¬°±Ò°Ê(startup)ªí³æ¡A«h¥¦ªº¤÷MDIForm·|¦Û°Ê³Q¸ü¤J¡A¦Ó¥B¦bMDI¤lªí³æ¬°¥i¨£(visible)¤§«eÅã¥Ü¡C°£¤F±Ò°Êªí³æ¥~¡A¨ä¾lªº¤lªí³æ³£¬O¨Ï¥ÎNewÃöÁä¦r¨Ó«Ø¥ß¹êÅé¡G

' Inside the MDIForm module
Private Sub mnuFileNew_Click()
    Dim frmDoc As New frmDocument
    frmDoc.Show
End Sub

MDIForm¼Ò²Õ´£¨Ñ¤@­ÓÃB¥~ªºÄÝ©Ê¡AAutoShowChildren¡C·í§Ú­Ì§â³o­ÓÄݩʳ]¬°True (¤º©w­È)¡AMDI¤lªí³æ·|¦b¤÷MDIForm¸ü¤J®É¥ß¨è³QÅã¥Ü¡C´«¥y¸Ü»¡¡A°£«D§â­È³]¬°False¡A§_«h¤£¯àÅý¤lªí³æ¦b¸ü¤J®É¤£­nÅã¥Ü¦bµe­±¤W¡C

MDI¤lªí³æ¦P¼Ë¤]¦³¯S®íªº©Ê½è¡CÁ|¨Ò¨Ó»¡¡A¥¦­Ì¤£¹³¤@¯ëªºªí³æ¤@¼Ë¦³Åã¥Ü¥\¯àªí¡G·í§Ú­Ì¹ïMDI¤lªí³æ·s¼W¤@©Î¦h­Ó¥\¯àªí¡A¥B·íªí³æÅܦ¨¥D°Ê®É(Active)¡A

¦b¤÷MDIForm¤¤¡A¤lªí³æ¥\¯àªí·|¨ú¥N­ì¨Óªº¤÷MDIForm¥\¯àªí¡C

¦]¬°³o­Ó­ì¦]¡A²ßºD¤W§Ú­Ì³£¤£·|ÅýMDI¤lªí³æ¥]§t¥\¯àªí¡A¦Ó¥u©w¸qMDIForm ¼Ò²Õªº¥\¯àªí¡C


¡@

¹Ï9-11 ¦b³]­p®É´ÁªºMDI NotepadÀ³¥Îµ{¦¡

·íMDIForm¼Ò²Õ¤Wªº¥\¯àªí«ü¥O³Q©I¥s®É¡A±z¥u»Ý§Q¥ÎActiveFormÄÝ©Ê¡A±N«ü¥OÀ³¥Î¦b²{¦b¥D°Ê(Active)ªºMDI¤lªí³æ¤W¡C¤U­±ªº¨Ò¤l¸Ñ»¡¦p¦ó°õ¦æFile¥\¯àªí¤¤ªºClose«ü¥O¡G

' In the MDI parent form
Private Sub mnuFileClose_Click()
    ' Close the active form, if there is one.
    If Not (ActiveForm Is Nothing) Then Unload ActiveForm
End Sub

±z¥²¶·ÀH®ÉÀˬd ActiveForm ÄÝ©Ê¡A¦]¬°¦³¥i¯à²{¶¥¬q¨S¦³¥ô¦óMDI¤lªí³æ¬O³Q¶}±Òªº¡A³o®É­Ô¡AActiveForm ÄÝ©Ê·|¶Ç¦^Nothing (¨Ã¤£¦p±z·Q¹³ªº·|¶Ç¦^MDIForm¥»¨­)¡C°²¨Ï±zªºMDIÀ³¥Îµ{¦¡¤ä´©¤£¦PºØÃþªºMDI¤lªí³æ¡A±z³q±`»Ý­n±oª¾Activeªºªí³æ¬O­þºØÃþ«¬ªº¡A¨Ò¦p¤U­±ªºµ{¦¡½X¡G

Private Sub mnuFilePrint_Click()
    If TypeOf ActiveForm Is frmDocument Then
        ' Print the contents of a TextBox control.
        Printer.Print ActiveForm.txtEditor.Text
        Printer.EndDoc
    ElseIf TypeOf ActiveForm Is frmImageViewer Then
        ' Print the contents of a PictureBox control.
        Printer.PaintPicture ActiveForm.picImage.Picture, 0, 0
        Printer.EndDoc
    End If
End Sub

µøµ¡¥\¯àªí
¡@

MDIForm´£¨Ñ¤@­Ó¤@¯ëªí³æ©Ò¨S¦³ªº¤èªk Arrange¡C³o­Ó¤èªk¥i´£¨Ñµ{¦¡§Ö³tªº±Æ¦C©Ò¦³ªºMDI¤lªí³æ¡C±z¥i¥HÅý©Ò¦³ªºMDI¤lªí³æ¤ô¥­¨Ã±Æ¡B««ª½¨Ã±Æ¡B­«Å|Åã¥Ü¡A©Î¬O±N¥¦­Ì³Ì¤p¤Æ¡A¨Ì§Ç§â¹Ï¥Ü±Æ¦bMDI¤÷ªí³æªº¤U¤è¡C­n¹F¨ì³o¨Ç¥Øªº¡A¦b«Ø¥ßµøµ¡¥\¯àªí®É»Ý¨Ï¥Î¥|­Ó«ü¥O¡GTile Horizontally¡BTile Vertically¡BCascade ¤Î Arrange Icons¡C©³¤U¬Oµ{¦¡½X¡G

Private Sub mnuTileHorizontally_Click()
    Arrange vbTileHorizontal
End Sub
Private Sub mnuTileVertically_Click()
    Arrange vbTileVertical
End Sub
Private Sub mnuCascade_Click()
    Arrange vbCascade
End Sub
Private Sub mnuArrangeIcons_Click()
    Arrange vbArrangeIcons
End Sub

³q±`§Ú­Ì·|²ßºD±N¤w¸g³Q¶}±ÒªºMDI¤lªí³æ¦WºÙ¦C¦b¥\¯àªí¤¤¡A¤è«K¨Ï¥ÎªÌ¥Î·Æ¹«ÂI¿ï¡A§Ö³tªº¤Á´«¨ì¥L­Ì©Ò»Ýªºªí³æ(¹Ï9-12)¡C¦bVisual Basic¤¤¥i¥H«Ü®e©ö¹ê²{³o­Ó¥\¯à¡G±z¥u»Ý¤Ä¿ï¦b¥\¯àªí½s¿è¾¹¤¤¥\¯àªíªºWindowList¿ï¶µ¡A¥¦­Ì¥i¥H¬O¦b³Ì¤W¼h¡A©Î¬O¦b°Æ¥\¯àªíÅã¥Ü²M³æ¡C»Ý­nª`·Nªº¬O¤£ºÞ±z¬O¿ï¾Ü­þ¤@ºØ¡A¥u¯à¦³¤@­Ó¥\¯àªí¶µ¥ØªºWindowList¿ï¶µ¥i¥H³Q¤Ä¿ï¡C


¡@

¹Ï9-12 Window¥\¯àªíÅý±z±Æ¦C©Ò¦³MDI ¤lªí³æ¨Ã¥B¥i¥H¨Ï¥Î·Æ¹«§Ö³tªº¤Á´«µøµ¡¡C

¦bMDI¤lªí³æ¤¤·s¼WÄÝ©Ê
¡@

¦bVisual Basicª©¥»3¤¤¡A­n¼¶¼gMDIªºÀ³¥Îµ{¦¡¨Ã¤£®e©ö¡A±z¥²¶·§Q¥Î¤@­ÓUDT«¬ºAªº°}¦C¨Ó°O¸ü¦UMDI¤lªí³æªºª¬ºA¡A¦b¦UMDI¤lªí³æ¶}±Ò©ÎÃö³¬®É¡A±z±N·|¦£©óºûÅ@³o­Ó°}¦C¡C¦bVisual Basicª©¥»4«á¡A¨Æ¥óÅܱo²³æ¤F¡A¦]¬°¨C­Óªí³æ³£¥i¥H¤ä´©¦Û­qªºÄÝ©Ê¡A¦Ó±z¥i¥H±N¸ê®Æª½±µ¦s©ñ¦b¨C­ÓMDI¤lªí³æ¼Ò²Õ¤¤¡A¤£»Ý­n¨Ï¥Î¤@­Ó¥þ°ìªºUDTs°}¦C¡C

¨C­ÓMDI¤lªí³æ¦Ü¤Ö·|¦³¨â­Ó¨å«¬ªº¦Û­qÄÝ©Ê¡GFilename ¤Î IsDirty (·íµM¡A¹ê»Ú¤Wªº¦WºÙ¥i¯à¤£¦P)¡CFilename Äݩʦs©ñªí³æ¸ü¤Jªº¸ê®ÆÀɮצWºÙ¡A¦Ó IsDirty °O¸üÀɮ׬O§_³Q¨Ï¥ÎªÌ§ó§ï¹L¡A¶Ç¦^ªº¬O¤@­Ó¥¬ªL­È¡C©³¤Uµ{¦¡¤¶²ÐMDI Notepad¥Ü½dµ{¦¡¦p¦ó¹ê§@¤W­z¨â­ÓÄÝ©Ê¡G

' Inside the frmDocument MDI child form
Public IsDirty As Boolean
Private m_FileName As String

Property Get Filename() As String
    Filename = m_FileName
End Property
Property Let Filename(ByVal newValue As String)
    m_FileName = newValue
    ' Show the filename on the form(tm)s Caption.
    Caption = IIf(newValue = "", "Untitled", newValue)
End Property

Private Sub txtEditor_Change()
    IsDirty = True
End Sub

¦³¤F IsDirty ÄÝ©Ê¡A°²³]¨Ï¥ÎªÌ§ïÅܤF¸ê®Æ¡A±z´N¥i¦bÃö³¬ªí³æ®É¸ß°Ý¨Ï¥ÎªÌ­n¤£­n¦sÀÉ¡A³o­Ó¤u§@­n¦bMDI ¤lªí³æªº Unload ¨Æ¥ó¤¤§¹¦¨¡G

Private Sub Form_Unload(Cancel As Integer)
    Dim answer As Integer
    If IsDirty Then
        answer = MsgBox("This document has been modified. " & vbCr _
            & " Do you want to save it?", vbYesNoCancel + vbInformation)
        Select Case answer
            Case vbNo
                ' The form will unload without saving data.
            Case vbYes
                ' Delegate to a procedure in the main MDI form.
                frmMainMDI.SaveToFile Filename
            Case vbCancel
                ' Refuse to unload the form.
                Cancel = True
        End Select
    End If
End Sub

MDI¦¬¯Ç¾¹ªº¦h«¬(Polymorphic)
¡@

¦b«e¤@¸`ªºMDI Notepad À³¥Îµ{¦¡¡A¥i¥H«Ü¥¿±`ªº¹B§@¡A¦ý¬O¨Ã¤£¯àµø¬°¬O¤@­Ó¦nªºª«¥ó¾É¦V³]­p¡C¨Æ¹ê¤W¡AMDIForm ª«¥ó¹H¤Ï¤FMDI¤lªí³æªº«Ê¸Ë©Ê¡A¦]¬°¥¦ª½±µ¦s¨úMDI¤lªí³æªºtxtEditor±±¨î¶µÄÝ©Ê¡CÁöµM³o¥u¬O­Ó¤p¯ÊÂI¡A¦ý´N¹³±z©Òª¾¹Dªº¡A¦nªº«Ê¸Ë¬O¼g¥X¥i­«ÂШϥΡB©ö©óºûÅ@¤Î¨S¦³¿ù»~ªºµ{¦¡(bug-free)ªºÃöÁä©Ò¦b¡Cµ§ªÌ±N¥Î¨â­Ó¤èªk¨Ó¥Ü½d³o­Ó·§©À¡C

©w¸qparent-child¤¶­±
¡@

­Y±z¤£·Q¤÷MDI ªí³æª½±µ¦s¨ú¤lªí³æªº±±¨î¶µ¡A¸Ñ¨Mªº¤èªk´N¬O©w¸q¤@²Õ¤¶­±¨ÓÅý¨âªÌ°µ·¾³q¡CÁ|¨Ò»¡©ú¡A¤÷MDIªí³æÀ³¸Ó­n¨D¤lªí³æ¦Û¤v¸ü¤J¡BÀx¦sÀɮסA¦Ó¤£¬Oª½±µ¨Ï¥Î¨ì¤lªí³æªº txtEditorÄÝ©Ê¡C¦P¼Ëªº¡A¤÷MDIªí³æÀ³¸Ó³z¹L©I¥s¤lªí³æªº¤èªk¨Ó­n¨D¦btxtEditor±±¨î¶µ°Å¤U¡B½Æ»s¤Î¶K¤W¸ê®Æ¡C¤÷MDIªí³æ¤]À³¸Ó¸ß°Ý¤lªí³æ¡A­þ¨Ç¦b¥\¯àªí-½s¿èªº©R¥O¬O¥i¨Ï¥Îªº¡C

¦b¼¶¼gMDI±M®×ªº¸gÅ礤¡Aµ§ªÌ¾ã²z¥X¤@­Ó²³æªº¤¶­±¡A¥i¥H²Å¦X¤@¯ëMDIÀ³¥Î¡Cµ{¦¡ªº­n¨D¡A°£¤F Filename ¤Î IsDirty ÄÝ©Ê¥~¡A³o­Ó¤¶­±ÁÙ¥]§t¹³ IsEmpty (­YMDI¤lªí³æ¨S¦³¥ô¦ó¸ê®Æ¡A¶Ç¦^True)¡BCanSave¡BCanCut¡BCanCopy¡BCanPaste ¤Î CanPrint ÄÝ©Ê¡B

Cut¡BCopy¡BPaste¡BPrintDoc¡BLoadFile¡BSaveFile ¤Î AskFilename(¥Î¦b FileOpen ©Î¬O FileSave ªº¼Ð·Ç¹ï¸Ü¤è¶ô¤¤)¡C³o­Ó¤¶­±¤¹³\±z¦b­«·s§ï¼gMDI NotepadÀ³¥Îµ{¦¡®É¡A¤£·|¯}ÃaMDI¤lªí³æªº«Ê¸Ë©Ê¡C¨Ò¦p¤U­±³o¬qµ{¦¡½X¹ê§@¤F¦bMDI¤÷ªí³æ¥\¯àªí¤¤ÀÉ®×Save as©R¥O¡G

Private Sub mnuFileSaveAs_Click()
    ' Ask the document to show a common dialog, and
    ' then save the file with the name selected by the user.
    On Error Resume Next
    ActiveForm.SaveFile ActiveForm.AskFilename(True)
End Sub

©³¤U¬O¹ê§@PrintDoc¤èªkªº¤lMDIªí³æ:

Sub PrintDoc()
    Printer.NewPage
    Printer.Print txtEditor.Text
    Printer.EndDoc
End Sub

·Ó¨Ò¡A³o­Óµ{¦¡ªº·sª©¥»¤]©ñ¦bÀH®Ñ¥úºÐ¤¤¡A±z·|µo²{¤ñª©¥»ªºµ{¦¡ªø¤F¤@ÂI¡A¦ý±z±N·|¥ß§Y¬Ý¨ì¨Ï¥Î·sµ²ºc©Ò±a¨Óªº¦n³B¡C


»¡©ú

¦b¥Ü½dµ{¦¡¤¤¡Aµ§ªÌ©w¸q¤F¤@²ÕÄݩʤΤèªk¡CµM«áµ§ªÌ§â¥¦­Ì©ñ¨ìfrmDocument MDI¤lªí³æªº¥D¤¶­±¤¤¡C¦]¬°frmMain MDI¥Dªí³æ¬O§Q¥Î ActiveForm ÄݩʨӦs¨ú¤lªí³æ¡A¦]¦¹³o­Ó¤¶­±ªºÄݩʤΤèªk¬OÄÝ©ó«á´Á³sµ²¡A³o¥Nªí±z¥²¶·¥Î On Error ±Ô­z¨Ó«OÅ@¨C­Ó¤Þ¥Î¡C­Y­n°µ±o§ó§¹¬ü¡A½Ð©w¸q¤@­Ó©â¶HÃþ§O·í§@²Ä¤G¤¶­±¡A¦Ó¦b©Ò¦³ªºMDI¤lªí³æ¼Ò²Õ³£¹ê§@²Ä¤G¤¶­±¡C


§ó§ïClientªí³æªº¹ê§@
¡@

¦]¬°·sª©¥»ªºMDI¤÷ªí³æ¤£·|¯}ÃaMDI¤lªí³æªº«Ê¸Ë©Ê¡A±z¥i¥H¥ô·N§ó§ïMDI¤lªí³æªº¹ê§@¤è¦¡¡A¦Ó¤£·|¤ÞÅT¨ì¥Dµ{¦¡¡C¨Ò¦p¡A±z¥i¥H§âNotepad§ï¦¨¤@­ÓMDI§Î¦¡ªº¼v¹³ÂsÄý¾¹¡C¦¹®ÉMDI¤lªí³æ·|©ñ¤@­ÓPictureBox±±¨î¶µ¡A¦Ó±z¥²¶·¹ê§@¤¶­±©Ò¦³ªºÄݩʤΤèªkÅýparent-child°µ·¾³q¡C§Q¦p¡APrintDoc ¤èªk²{¦b§ï¬°¡G

Sub PrintDoc()
    Printer.NewPage
    Printer.PaintPicture picBitmap.Picture, 0, 0
    Printer.EndDoc
End Sub

¥O¤HÅå³Yªº¬O¡A¥u»Ý§ó§ï¤Ö©ó20¦æªºµ{¦¡½X¡A´N¥i¥H§âMDI Notepad±M®×Âন¤@­Ó¼v¹³ÂsÄý¾¹¡C³Ì¥O¤H¿³¾Äªº¤@ÂI´N¬O±zµ·²@¤£¥Î¥h§ó§ïfrmMain ¼Ò²Õªºµ{¦¡¡C´«¥y¸Ü»¡¡A±z«Ø¥ß¤F¤@­Ó¥i­«ÂШϥΡA¦h«¬ªºMDI¤÷ªí³æ¡I

¬Æ¦Ü¡A§Ú­Ì¥u­nµy·L§ó§ïMDI¤÷ªí³æªºµ{¦¡¡A´N¥i¥HÅý¤£¦P«¬ºAªº¤lªí³æ¦@¦s©ó¤@­ÓMDI¦¬¯Ç¾¹¤¤¡A¹Ï9-13¬O·sª©¥»ªº½d¨Òµ{¦¡¡A¥i¥H¦P®É¦s¦b¤å¦r¤å¥ó¤Î¼v¹³¡C¦Ò¼{¨ìÃB¥~»Ý­nªºÄݩʤΤèªk¡A±z¥i¥H·s¼W¤lªí³æªº«¬ºA¡A©Î¬OÂX¥R¤¶­±¨Ó¸Ñ¨M¡C


¡@

¹Ï9-13 ±z¥i¥H­«ÂЧQ¥ÎfrmMain MDIªí³æ¡A¨Ó·f°t¤£¦P¥\¯àªº¤lªí³æ¡A¦p¤p«¬ªº¤å®Ñ³B²z¾¹©Î¼v¹³ÂsÄý¾¹¡C

À³¥Îµ{¦¡ºëÆF
¡@

Visual Basic 6´£¨Ñ·sª©ªºÀ³¥Îµ{¦¡ºëÆF¡A¥¦¤ñVisual Basic 5´£¨Ñªºª©¥»§ó¨ã¼u©Ê¡A¥B»P¤u¨ã¦CºëÆF¤Îªí³æºëÆF§¹¾ã¦a¾ã¦X¡C

¦b¦w¸ËVisual Basic®É¡A´N¤@¨Ö¦w¸Ë¤FÀ³¥Îµ{¦¡ºëÆF¡A¦]¦¹§Ú­Ì¥u­n²³æªº±q¼W¯q¶°ªº¼W¯q¥\¯àºÞ²z­û¤¤¿ï¨ú§Y¥i¡C·í±z°õ¦æ³o­ÓºëÆF¡A±z¥i¥H¿ï¾Ü¦h­«¤å¦r¤¶­±(MDI)³æ¤@¤å¦r¤¶­±(SDI)©Î¬OÃþ¦üÀÉ®×Á`ºÞªº¤¶­± (Windows Explorer-like) ¦p¹Ï 9-14¡C

­Y±z¿ï¾Ü¦h­«¤å¦r¤¶­±¡AºëÆF·|­n¨D±z³]©w¥\¯àªí(¹Ï9-15)¡G·í±z»s§@¼Ð·Çªº¥\¯àªí®É¡A¥i¯à·|§Æ±æ¨Ï¥Î¹³³o»ò²³æ¤Îª½Ä±¦¡ªº¤u¨ã¡C


¡@

¹Ï9-14 À³¥Îµ{¦¡ºëÆF¡G¿ï¾Ü¤¶­±Ãþ«¬¡C


¡@

¹Ï9-15 À³¥Îµ{¦¡ºëÆF¡G¿ï¾Ü¥\¯àªí¡C

¤U¤@¨B¡A§Q¥Î¤º«ØªººëÆF¨Ó¦Û­q¤u¨ã¦C (¹Ï9-16)¡C³o­ÓÆF¥©ªº¤u¨ã¡A±z¤]¥i¦b¼W¯q¶°¿ï³æ¤º§ä¨ì¦W¬°ToolbarºëÆF¡C

±µ¤U¨Óªº¨BÆJ¡AÀ³¥Îµ{¦¡ºëÆF·|¸ß°Ý±z­n¤£­n¨Ï¥Î¸ê·½ÀÉ¡A¥H¤Î¬O§_­n¦bHelp¿ï³æ¤¤©ñ¤J¤@­Ó¿ï¶µ¡A¥i¥HÅý¨Ï¥ÎªÌ³sµ²¨ì±zªºWeb¯¸¥x¡C±z¤]¥i¿ï¾Ü¥[¤J¨ä¥¦ªºªí³æ¨ì±M®×¤¤¡A¥]§t¥|ºØ¼Ð·Çªí³æ¡A©Î¬O±z¤§«e©w¸q¹Lªºªí³æ½d¥»¡C³Ì«á¡A±z¥i¥ô·N¼W¥[¸ê®Æªí³æ¡A¦¹®É¡AºëÆF·|©I¥sµ§ªÌ¦b ²Ä¤K³¹ ´y­zªº¸ê®Æªí³æºëÆF¡C

¦b³Ì«á¤@¨BÆJ¡A±z¥i¥H¨M©w¬O§_­n§â³]©w­ÈÀx¦s¦b¤@­Ó²ÕºAÀɤ¤¡A¥H«K¤U¤@¦¸°õ¦æÀ³¥Îµ{¦¡ºëÆF®É¥i¥H¬Ù²¤¤W­z¨BÆJ¡C


¡@

¹Ï9-16 À³¥Îµ{¦¡ºëÆF¡G¦Û­q¤u¨ã¦C¡C


¡@

¹Ï9-17À³¥Îµ{¦¡ºëÆF¡G¥[¤J¼Ð·Çªí³æ¡C

ÁöµM¦b±z«Ø¥ßMDIÀ³¥Îµ{¦¡®É¡AÀ³¥Îµ{¦¡ºëÆF©Ò²£¥Íªºµ{¦¡½X¬O­Ó¦nªº¥XµoÂI¡A¦ý¦bµ§ªÌªº¬Ýªk¡A³o¨Çµ{¦¡½XÁÙ¬O¦³«Ü¦h»Ý­n§ï¶iªº¦a¤è¡CºëÆF©Ò²£¥ÍªºMDIÀ³¥Îµ{¦¡¡A¦s©ñ¤@­Ó¥]§tRichTextBox±±¨î¶µªºÂ²³æMDI¤lªí³æ¡A¨Ó«Ø¥ß¤å®Ñ³B²z¾¹«¬ºAªºÀ³¥Îµ{¦¡¡CµM¦Ó¡A¦b¬Y¨Ç³õ¦X¡A¤u¨ã¦C¤Wªº«ö¶s¨Ã¤£¹³´Á±æ¤¤ªº¹B§@¡A¦Ó¥B©Ò¦³Ãö©ó³]©w³q¥Î¹ï¸Ü¤è¶ô(common dialog)ªºµ{¦¡½X¡A¤]¤£·|¦Û°Ê¥¿½T²£¥Í¡A³o¬O¥¦ªº¤@¨Ç¯ÊÂI¡C¤£©¯¦a¡A±zµLªk±±¨îºëÆF¦p¦ó²£¥Íµ{¦¡½X¡A©Ò¥H¨C¦¸°õ¦æ§¹ºëÆF«á¡A±zÁÙ¬O¥²¶·¤â°Ê¦a§ó§ï©Ò²£¥Íªºµ{¦¡¡C

¨Ï¥Î©ì©ñ¥\¯à (DRAG-AND-DROP)
¡@

Visual Basic¦b¦­´Áªºª©¥»´N¦³¥]§tdrag-and-dropªº¯à¤O¡A¦ý¥u¦³¦bVisual Basic 5·s¼W¤F¥t¤@²ÕÄÝ©Ê¡B¤èªk¤Î¨Æ¥ó«á¡A¤~¦³¹ê²{OLE-compliant¾÷¨î¤Î¸óÀ³¥Îµ{¦¡(cross-application)ªº©ì©ñ¯à¤O¡C

¦Û°Ê©ì©ñ¼Ò¦¡
¡@

°ò¥»¤W¡A¤@­Ó±±¨î¶µ¥i¥H¬O©ì©ñ°Ê§@ªº¨Ó·½©Î¥Øªº¡CVisual Basic´£¨Ñ¨âºØ©ì©ñ¼Ò¦¡¡A¦Û°Ê¼Ò¦¡©Î¤â°Ê¼Ò¦¡¡C¦b¦Û°Ê¼Ò¦¡¤¤¡A±z¥u­n¦b°õ¦æ®É´Á³]©w¤@­ÓÄÝ©Ê¡A°õ¦æ®É¡AVisual Basic·|À°±z¦Û°Ê³B²z¨ä¥¦¸Ó°µªº¡C¬Û¤Ï¦a¡A¦b¤â°Ê¼Ò¦¡¤U¡A±z¥²¶·¹ï©ì¦²¹Lµ{¤¤²£¥Íªº¤@¨t¦C¨Æ¥ó°µ³B²z¡A¦ý´«¨Óªº¬O¹ï©ì©ñ¹Lµ{§ó¦nªº±±¨î¡C

¤j¦h¼ÆVisual Basic¤º«Øªº±±¨î¶µ¤Î¤Ö¼Æªº¥~³¡ActiveX±±¨î¶µ³£¤ä´©¤£¦Pªí³æ¶¡ªºOLE-©ì©ñ¡C¦Ó¤Ö¼Æªº±±¨î¶µ¥u¯à³Q·í§@©ì©ñ§@·~ªº¥Øªº±±¨î¶µ¡C¥t¥~¡A¥u¦³¤Ö¼Æªº¤º«Øª«¥ó¥i¨Ï¥Î¦Û°Ê¼Ò¦¡¡C³]©w OLEDragMode ÄÝ©Ê¥i¥H¨M©w¨Ó·½±±¨î¶µ¦b©ì©ñ§@·~ªº¦æ¬°¡C¦P¼Ëªº¡A³]©w OLEDropMode ÄÝ©Ê¥i¥H¨M©w¥Ø¼Ð±±¨î¶µ¦b©ì©ñ§@·~ªº¦æ¬°¡Cªí9-1²¦C¥X¤º«Ø±±¨î¶µ¡A¤Î¤@¨ÇActiveX±±¨î¶µ¹ï©ì©ñªº¤ä´©µ{«×¡C

Controls OLEDragMode OLEDropMode
TextBox, PictureBox, Image, vbManual, vbNone, vbManual
RichTextBox, MaskEdBox vbAutomatic vbAutomatic
ComboBox, ListBox, DirListBox, vbManual, vbNone, vbManual
FileListBox, DBCombo, DBList, TreeView, ListView, ImageCombo, DataList, DataCombo vbAutomatic  
Form, Label, Frame, Not supported vbNone, vbManual
CommandButton, DriveListBox, Data, MSFlexGrid, SSTab, TabStrip, Toolbar, StatusBar, ProgressBar Slider, Animation, UpDown, MonthView, DateTimePicker, CoolBar    
ªí 9-1 ±z¥i¥H¨Ì·Ó±±¨î¶µ¹ï©ì©ñªº¤ä´©µ{«×¨Ó¤ÀÃþ¡A¦b«Dµøµ¡µ{¦¡®w¤¤ªº±±¨î¶µ¡A»P¤º«Ø±±¨î¶µªº¤ä´©µ{«×¤@¼Ë¡C

°²¨Ï¤@­Ó±±¨î¶µ¤ä´©¦Û°Ê¼Ò¦¡ªº©ì©ñ¡A±z¥u­n±N¥¦ªº OLEDragMode ©Î¬O OLEDropMove ªºÄݩʳ]¬°vbAutomatic¡C¨Ò¦p¡A­Y±z§Æ±æµ{¦¡¤¤¤ä´©RTF¤å¦r®æ¦¡ªº©ì©ñ¡A±z¥u¶·©ñ¸m¤@­ÓRichTextBox±±¨î¶µ¨ìªí³æ¤W¡A¨Ã¥B§â¥¦ªº OLEDragMode ¤Î OLEDropMode Äݩʳ]¬°1-vbAutomatic¡C¦p¦¹¡A±z«K¥i¥H±q Microsoft Word¡BWordPad¤Î¤j¦h¼Æªº¤å®Ñ³B²z¾¹¤¤©ì¦²³¡¤Àªº¤å¦r¨ìRichTextBox¤¤¡C·íµM¡A±z¤]¥i¥H¹ïµ{¦¡¤¤¨ä¥LªºRichTextBox±±¨î¶µ§@©ì©ñ°Ê§@¡ATextBox¤ÎMaskEdBox±±¨î¶µ¤]¬O¤@¼Ë¡A´N¹³±z¦b¹Ï9-18©Ò¬Ý¨ìªº¡C

¨ä¥¦ªº±±¨î¶µ¤]¤ä´© OLEDragMode Äݩʪº³]©w¡C¦ý¦b¬Y¨Ç±¡ªp¤U¡A³o¨Ç¦Û°Ê©ì©ñ¼Ò¦¡ªº°Ê§@¥i¯à¤£¦p±z¹w´Á¡C¬Ý¬Ý¥i¯àªº±¡ªp¡G±z¥i¥H±q¤@­Ó¥i½Æ¿ïªº¶µ¥Ø²M³æ(ListBox)±±¨î¶µ¤¤¡A©ì¦²´X­Ó©Ò¿ï¾Üªº¶µ¥Ø¨ì¤@­Ó¤¹³\¦h¦æ¤å¦rªº¤å¦r¤è¶ô(TextBox)±±¨î¶µ¤¤¡A«h³o¨Ç¶µ¥Ø·|¦b¤å¦r¤è¶ô¤¤¥HCR-LF¨Ó¤À¹j¡C¥t¤@­Ó±¡ªp¬O§âFileListBox±±¨î¶µ¤¤©Ò¿ï¾Üªº¶µ¥Ø©ñ¨ì¨ä¥L¤ä´©³o¨Ç¶µ¥ØªºWindows À³¥Îµ{¦¡¤¤¡C¨Ò¦p¡A¦bÀH®Ñ¥úºÐ¤¤ªº¥Ü½dµ{¦¡¡A±z¥i¥H§âDOC©ÎTXT°ÆÀɦWªº¶µ¥Ø©ñ¨ìMicrosoft Word¤¤¡C½Ðª`·N¤@ÂI¡AÁöµMDirListBox©x¤è¤ä´©¦Û°Ê©ì©ñ¼Ò¦¡ªº OLEDragMode¡A¹ê»Ú¤W¦b¾Þ§@®É¨Ã¤£·|¦³dragªº°Ê§@¡C


¡@

¹Ï9-18 ³o­Óµ{¦¡¥Ü½d±z¦p¦ó©ì©ñ¤å¦r©Î¼v¹³¨ì¥t¤@­Óµøµ¡µ{¦¡¡C½ÐÆ[¹î¤å¦r¦bRichTextBox¤ÎTextBox±±¨î¶µ¤¤¡AÂà´«¦¨¤£¦Pªº¤è¦¡¨Ó§e²{¡C

·í¨Ï¥Î¦Û°Ê©ì©ñ¼Ò¦¡®É¡A±zªºÀ³¥Îµ{¦¡¤£·|±µ¦¬¨ì¥ô¦ó¨Æ¥ó¡A¦Ó±z¤]µLªk±±¨î©ì©ñªº¹Lµ{¡C¥u¦³¦b¨Ï¥Î·Æ¹«¥ªÁä¥i¥H¶}©l©ì©ñ§@·~¡A¹w³]ªº®ÄªG¬OMove©R¥O(·N«ü¸ê®Æ·h²¾¨ì¥Øªºª«¥ó¡AµM«á¦b¨Ó·½±±¨î¶µ¤¤§R°£)¡C°²¨Ï­n°õ¦æ½Æ»sªº°Ê§@¡A±z¥²¶·¹³¦bWindow Explorer¤@¼Ë¡A«ö·Æ¹«¥ªÁä®É¦P®É«ö¤UCtrlÁä¡C

¤â°Ê©ì©ñ¼Ò¦¡
¡@

ÁöµM¦Û°Ê©ì©ñ¼Ò¦¡¤¤Åý±z¥u­n²³æªº¦b³]­p®É´Á³]©w¤@¨ÇÄÝ©Ê¡A´N¥i¹F¨ì¦³½ìªº©ì©ñ®ÄªG¡C¦ý«ÜÅãµM¦a¡A­nµo´§©ì©ñªº§ó¤j«Â¤O¡A´N¥²¶·¨Ï¥Î¤â°Êªº©ì©ñ¼Ò¦¡¡C±µ¤U¨Ó±z±N·|¬Ý¨ì¡A­n§¹¦¨©ì©ñªº¹Lµ{¡A¤£ºÞ¬O¦b¨Ó·½©Î¬O¥Ø¼Ðª«¥ó¡A§Ú­Ì¥²¶·¦b´X­Ó¯S©w¨Æ¥ó¤¤¼¶¼gµ{¦¡¡C¹Ï9-19²³æ¦C¥X·í¨Ï¥ÎªÌ°õ¦æ©ì©ñ®É·|²£¥Íªº¨Æ¥ó¡A±z¥i¯à¦b«áÄòªº¤p¸`·|°Ñ¦Ò¨ì³o­Ó¹Ïªí¡C


¡@

¹Ï9-19 ©Ò¦³¦b¤â°Ê¼Ò¦¡¤¤·|²£¥Íªº¨Æ¥ó

¦b¹Ï9-20¤¤ªº¥Ü½dµ{¦¡¬O¥Ñ¥i§@¬°OLE ©ì©ñ¹Lµ{¤¤¨Ó·½¤Î¥Ø¼ÐªºRichTextBox±±¨î¶µ©Ò²Õ¦¨¡C¦bªí³æ¤W¦P¼ËÁÙ¦³¤@­ÓListBox±±¨î¶µ¡A¥¦¥iÅý±z©ñ¸m¥ÑRichTextBox±±¨î¶µ©Î¬O¨ä¥L¨Ó·½(¦pMicrosoft word)ªº¯Â¤å¦r¸ê®Æ¡C·í±z°õ¦æ©ì©ñ°Ê§@®É¡AListBox±±¨î¶µ·|±½´y³o¬q¤å¦r¡A§â©Ò¦³¤£­«½Æªº³æ¦r­«·s±Æ§ÇÅã¥Üµ¹¨Ï¥ÎªÌ¡C


¡@

¹Ï9-20 ³o­Ó¥Ü½dµ{¦¡±N®i¥Ü¦p¦ó§Q¥ÎVisual BasicªºOLE©ì©ñ¯à¤O¡A¨Ó«Ø¥ß¤@­Ó¯à¦Û°Ê¤ÀªR¤å¦r¨Ó§ä¥X¤£­«ÂЪº³æ¦r¡A¨Ã¥B«ö¦r¥À±Æ§ÇªºListBox±±¨î¶µ¡C

±Ò°Ê©ì©ñªº°Ê§@
¡@

¦pªG±z§Æ±æ¯à°÷±Ò°Ê©ì©ñªº°Ê§@¡A´N¥²¶·§â OLEDragMode ªºÄݩʳ]¬° Visual BasicManual (°£¤FRichText¥~¡A©Ò¦³ªº±±¨î¶µ¹w³]­È¬Ò¬°Visual BasicManual)¡AµM«á©I¥s OLEDrag ¤èªk¨Ó¶}©l©ì¦²ªº¹Lµ{¡C³q±`§Ú­Ì·|¦b MouseDown ¨Æ¥óµ{§Ç¤¤©I¥s¡G

Private Sub rtfText_MouseDown(Button As Integer, Shift As Integer, _
    x As Single, y As Single)
    ' Start a drag operation if right button is pressed.
    If Button = 2 Then rtfText.OLEDrag
End Sub

·í±z©I¥s OLEDrag ¤èªk®É¡A¦b¨Ó·½±±¨î¶µ·|²£¥Í¤@­Ó OLEStartDrag ¨Æ¥ó¡C³o­Ó¨Æ¥ó·|±µ¦¬¤@­ÓDataObject ª«¥ó¡A¥H¤Î¤@­Ó AllowEffects °Ñ¼Æ¡C±z¥i¥H§âDataObjectª«¥ó¬Ý°µ¬O¤@­Ó®e¾¹¡A¥¦·|¥Î¨Ó¦s©ñ±z·Q­n±q¨Ó·½±±¨î¶µ¶Ç»¼¨ì¥Ø¼Ð±±¨î¶µªº¸ê®Æ¡A³o­Ó°Ê§@¬O³z¹L SetData ¤èªk¨Ó¹F¦¨¡C³o´N¦n¹³±z¥i¥H§Q¥ÎClipboard¨Ó¦s©ñ¤£¦PºØÃþªº¸ê®Æ¡A¦pªí9-2¡C¨Ò¦p¡ARichTextBox±±¨î¶µ¥i¥H·h²¾¡B½Æ»sRTF©Î¬O¯Â¤å¦r¸ê®Æ¡G

Private Sub rtfText_OLEStartDrag(Data As RichTextLib.DataObject, _
    AllowedEffects As Long)
    ' Use selected text, or all text if no text is currently selected.
    If rtfText.SelLength Then
        Data.SetData rtfText.SelRTF, vbCFRTF
        Data.SetData rtfText.SelText, vbCFText
    Else
        Data.SetData rtfText.TextRTF, vbCFRTF
        Data.SetData rtfText.Text, vbCFText
    End If
    AllowedEffects = vbDropEffectMove Or vbDropEffectCopy
End Sub
C onstant Value Meaning
vbCFText 1 Text
vbCFBitmap 2 Bitmap (BMP)
vbCFMetafile 3 Metafile (WMF)
vbCFEMetafile 14 Enhanced metafile (.emf)
vbCFDIB 8 Device independent bitmap (dib or bmp)
vbCFPalette 9 Color palette
vbCFFiles 15 List of files
vbCFRTF -16639 Rich Text Format (RTF)
ªí9-2 DataObject ª«¥ó©Ò¤ä´©ªºÃþ«¬¡C

±z¥²¶·¦b AllowedEffects °Ñ¼Æ¤¤«ü©w±z­n¦b©ì©ñ§@·~¤¤¨Ó·½¤¸¥ó¥i¤ä´©ªº°Ê§@¡C±z¥i¥H«ü©w1-vbDropEffectCopy ©Î¬O 2-vbDropEffectMove¡A­Y±z»Ý­n¦P®É¤ä´©¨â­Ó°Ê§@¡A¥i¥H«ü©w¨â­Ó­Èªº©M¡A´N¹³«e­±ªºµ{¦¡¤ùÂ_¡C

·Ç³Æ©ñ¸m¨ì¨Ó·½±±¨î¶µ
¡@

¦b©ì¦²§@·~¶}©l«á¡A·í·Æ¹«¸g¹L¥ô¦ó¤@­Ó±±¨î¶µ®É¡AVisual Basic·|¦b¸Ó±±¨î¶µ²£¥Í OLEDragOver ¨Æ¥ó¡C³o­Ó¨Æ¥ó·|±µ¦¬°£¤F¨Ó·½ª«¥ó©Ò³]©wªº DataObject ¤Î Effect¡AÁÙ¦³·Æ¹«®y¼Ð¤Î«ö¶sª¬ºA¡Cµ{¦¡¨Ì¾Ú³o¨Ç¸ê®Æ¡A§â Effect °Ñ¼Æ³]©w¬°¨ä¥i¥H°õ¦æªº°Ê§@¤§¤@¡A¥H«K½T©w·í¨Ï¥ÎªÌ±N¨Ó·½ª«¥ó©ì©ñ¨ì¤¸¥ó¤W®É¸Ó°õ¦æ­þ­Ó°Ê§@¡C³o­Ó­È¥i¥H¬O 0-vbDropEffectNone¡B1-vbDropEffectCopy¡B2-vbDropEffectMove©Î¬O3-vbDropEffectScroll («ü¥Ø¼Ð±±¨î¶µ·|±²°Ê¦Û¤vªº¤º®e¡A¨Ò¦p¡A·í·Æ¹«¦bListBox ±±¨î¶µ¤Wªºscrollbar®É)¡C State °Ñ¼Æ¥Nªí·Æ¹«¥¿­n¶i¤J©Î¬OÂ÷¶}±±¨î¶µ¡A¥i¥H¬O©³¤Uªº­È0-vbEnter¡B1-vbLeave ¤Î2-vbOver¡C

Private Sub lstWords_OLEDragOver(Data As DataObject, Effect As Long, _
    Button As Integer, Shift As Integer, X As Single, Y As Single, _
    State As Integer)
    If Data.GetFormat(vbCFText) Then
        Effect = Effect And vbDropEffectCopy
    Else
        Effect = vbDropEffectNone
End If
    ' As a demonstration, change the background of this ListBox when
    ' the mouse is over it.
    If State = vbLeave Then
        ' Restore background color on exit.
        lstWords.BackColor = vbWindowBackground
    ElseIf Effect <> 0 And State = vbEnter Then
        ' Change background color on entry.
        lstWords.BackColor = vbYellow
    End If
End Sub

¥Ø¼Ð±±¨î¶µ¥²¶·Àˬd¦Û¤v¬O§_¤ä´©DataObject ª«¥ó©Ò¥]§tªº¸ê®Æ«¬ºA¡C³o­Ó°Ê§@ÂǥѩI¥s DataObject ªº GetFormat ¤èªk¨Ó¹F¦¨¡A´N¹³¤W­±ªºµ{¦¡¤ùÂ_¡C¥t¥~±z¥²¶·ª¾¹D Effect °Ñ¼Æ¬O¤@­Ó¦ì¤¸Äæ¦ì(bit-field)ªº«¬ºA¡C

Effect = Effect And vbDropEffectCopy

¦b«e­±ªº¨Ò¤l¡A­Y¨Ó·½±±¨î¶µ¤£¤ä´©Copy°Ê§@¡A³¯­z¦¡ Effect=Effect And vbDropEffectCopy±N·|§âEffect ³]¬°0¡C­è¶}©l¡A±z¥i¯à»{¬°Äµ§i¬O¤Ó¹L«×¤F¡A¦]¬°±zª¾¹DRichTextBox±±¨î¶µ¤ä´©Copyªº°Ê§@¡C¦ý¬O±z¥²¶·°O¦íªº¬O¡A·í±z­nÅýlstWords±±¨î¶µ¯à¨Ï¥Î©ì©ñ§@·~¡A¥¦¦³¥i¯à¦b©ì©ñ¤¤¡A±µ¦¬¨ì¦UºØ¥i¯àªº¨Ó·½¡A¤£ºÞ¬O±q¥¦¥»¨­©ÒÄݪºÀ³¥Îµ{¦¡©Î¬O¥~­±ªºÀ³¥Îµ{¦¡¡A¦]¦¹¡A±z¥²¶·ÀH®É·Ç³ÆÀ³¥I¦UºØ¥i¯àªº±¡ªp¡C

¦b¨Ó·½±±¨î¶µ¤¤¡A·í OLEDragOver ¨Æ¥óµo¥Í«áºò¸òµÛµo¥ÍOLEGiveFeedback ¨Æ¥ó¡C¦b³o­Ó¨Æ¥ó¤¤¡A¨Ó·½±±¨î¶µ¯àª¾¹D¥Ø¼Ð±±¨î¶µ©Ò¿ï¾Üªº°Ê§@¡A¨Ã¥i¥H§ïÅܷƹ«´å¼Ð¡G

Private Sub lstWords_OLEGiveFeedback(Effect As Long, _
    DefaultCursors As Boolean)
    ' If effect is Copy, use a custom cursor.
    If Effect = vbDropEffectCopy Then
        DefaultCursors = False
        Screen.MousePointer = vbCustom
        ' imgCopy is an Image control that stores a custom icon.
        Screen.MouseIcon = imgCopy.Picture
    Else
        DefaultCursors = True
    End If
End Sub

­Y±z­n¨Ï¥Î¤£¦Pªº·Æ¹«´å¼Ð¡A¥²¶·±N DefaultCursors °Ñ¼Æ³]¬°False¡C·í±z¤£»Ý²z·|´å¼Ðªº§Îª¬®É¡A¨Ã¤£»Ý­n¹ê§@ OLEGiveFeedback ¨Æ¥ó¡C

©ñ¤U¸ê®Æ
¡@

·í¨Ï¥ÎªÌ¦b¥Ø¼Ð±±¨î¶µ©ñ¶}·Æ¹««öÁä®É¡A·|¦b¥Ø¼Ð±±¨î¶µ²£¥Í OLEDragDrop ¨Æ¥ó¡C°£¤F State °Ñ¼Æ¥~¡A³o­Ó¨Æ¥ó±µ¦¬ªº°Ñ¼Æ¸ò¦b OLEDragOver ¨Æ¥ó¤¤¤@¼Ë¡C¦b³o­Ó±¡ªp¤¤¡AEffect °Ñ¼Æªº·N¸q¦³¨Ç¤£¦P¡A ²{¦b¥¦¥Nªí¥Ø¼Ð±±¨î¶µ©Ò¨M©wªº°Ê§@¡C

Private Sub lstWords_OLEDragDrop(Data As DataObject, Effect As Long, _
    Button As Integer, Shift As Integer, X As Single, Y As Single)
    ' Restore the correct background color.
    lstWords.BackColor = vbWindowBackground
    ' Select Copy action if possible, otherwise select Move.
    If Effect And vbDropEffectCopy Then
        Effect = vbDropEffectCopy
    ElseIf Effect And vbDropEffectMove Then
        Effect = vbDropEffectMove
    End If
    ' In either case, ask for the data - only plain text is supported.
    Dim text As String
    text = Data.GetData(vbCFText)
    ' Code for processing the text and loading the list of unique
    ' words in the lstWords listbox (omitted)...
End Sub

ºò±µµÛ OLEDragDrop ¨Æ¥ó«á¡A·|¦b¨Ó·½±±¨î¶µ²£¥Í OLECompleteDrag ¨Æ¥ó¡C±z¥²¶·¦b³o­Ó¨Æ¥ó¤¤¼¶¼gµ{¦¡½X¡G·í·h²¾°Ê§@®É(vbDropEffectMove)¡A±z¥²¶·§â¨Ó·½±±¨î¶µ¤¤ªº¤Ï¥Õ°Ï§R°£¡A©Î¬OÁÙ­ì¦b©ì©ñ§@·~¤¤±±¨î¶µ©Ò³Q§ó§ïªº¥~Æ[¡G

Private Sub rtfText_OLECompleteDrag(Effect As Long)
    If Effect = vbDropEffectMove Then
        ' If this was a Move operation, delete the highlighted text.
        rtfText.SelText = ""
    Else
        ' If it was a Copy command, just clear the selection.
        rtfText.SelLength = 0
    End If
End Sub

¦b»Ý­n®É¸ü¤J¸ê®Æ
¡@

·í¨Ó·½±±¨î¶µ¤ä´©«Ü¦hªº«¬ºA¡A¦b OLEStartDrag ¨Æ¥óµo¥Í®É¡A§â³o¨Ç«¬ºA¸ê®Æ¤@¦¸³£¸ü¤J¨ìDataObject ª«¥ó¡A¨Ã¤£¬O«Ü¦³®Ä²vªº¸Ñ¨M¿ìªk¡C«Ü©¯¹B¦a¡AVisual Basic´£¨Ñ¤F¥t¤@ºØ¤èªk¡A¦b©ì¦²§@·~¶}©l®É¡A±z¥u­n«ü©w¨Ó·½±±¨î¶µ±N·|¤ä´©­þ¨Ç«¬ºA¡A¨Ó¨ú¥N§â¨Ó·½¸ê®Æ¸ü¤J¨ìDataObject ª«¥ó¤¤¡C

°²¨Ï©ì©ñ§@·~¥¼³Q¨ú®ø¡A¥Ø¼Ð±±¨î¶µ³Ì«á·|©I¥sDataObjectªº GetData ¤èªk¥h¨ú±o¬Û¹ï©Ò»Ý«¬ºAªº¸ê®Æ¡A¦¹®É¡AVisual Basic·|¦b¨Ó·½±±¨î¶µµo¥Í OLESetData ¨Æ¥ó¡G

Private Sub rtfText_OLESetData(Data As RichTextLib.DataObject, _
    DataFormat As Integer)
    ' This event fires only when the target control invokes the
    ' Data(tm)s GetData method.
    If DataFormat = vbCFText Then
        If rtfText.SelLength Then
            Data.SetData rtfText.SelText, vbCFText
        Else
            Data.SetData rtfText.text, vbCFText
        End If
    ElseIf DataFormat = vbCFRTF Then
        If rtfText.SelLength Then
            Data.SetData rtfText.SelRTF, vbCFRTF
        Else
            Data.SetData rtfText.TextRTF, vbCFRTF
        End If
    End If
End Sub

¦ý»Ýª`·Nªº¬O¡A¦b©ì©ñ§@·~¶}©l¡A­Y±z§â¸ê®Æ¶Ç¤J SetData ²Ä¤@­Ó°Ñ¼Æ®É¡A¨Ã¤£·|µo¥ÍOLESetData¨Æ¥ó¡C

©ì©ñÀÉ®×
¡@

´N¹³±z©Òª¾¹Dªº¡AWindowsÀÉ®×Á`ºÞ( Windows Explorer) ¥i¥H´£¨ÑÀɮצWºÙªº©ì©ñ¡A¦Ó«Ü¦hµøµ¡À³¥Îµ{¦¡¥i¥H¦bÀÉ®×Á`ºÞ¤¤·í§@¶}©l©ì¦²§@·~ªº¥Ø¼Ð¡C¦b³o¤@¸`¡A§Ú­Ì±N§i¶D±z¦p¦ó¹ê§@³o¨â­Ó¥\¯à¡Ð¥i¥H·í§@©ì©ñÀɮתº¨Ó·½©Î¬O¥Ø¼Ðªºµ{¦¡¡C

­n§¹¦¨³o­Ó¥\¯àªºÃöÁä¡A´N¬ODataObjectªº File ÄÝ©Ê¡C­Y»Ý­n±N±zªºÀ³¥Îµ{¦¡·í§@Àɮשì©ñ§@·~ªº¥Ø¼Ð¡A«h¥²¶·ÀˬdDataObjectª«¥ó¬O§_¦³vbCFFiles®æ¦¡ªº¸ê®Æ¡AµM«á§Q¥Î°j°é±qÀɮ׶°¦X¤¤Åª¨úÀɮצWºÙ¶i¨Ó¡CÁ|¨Ò¨Ó»¡±z¥i¥H¥Î©³¤Uªºµ{¦¡¨ÓŪ¨ú©ì©ñ¨ìListBox±±¨î¶µªºÀɮצWºÙ¡G

If Data.GetFormat(vbCFFiles) Then
    For i = 1 To Data.Files.Count
        lstFiles.AddItem Data.Files(i)
    Next
End If

·íµM¡A±z¤]¥i¥H¶}±Ò³o­ÓÀɮרåBÅã¥Ü¥¦¡C¦b¹Ï9-21ªº½d¨Òµ{¦¡¡A¹ê§@¤F¤W­zªº¥\¯à¡C


¡@

¹Ï9-21 ¤W¼hªºµøµ¡®i¥Ü±qWindows ÀÉ®×Á`ºÞ©ì¨ÓªºAutoDrop.vbpÀɮפº®e

¦Ó¤U¼hªºµøµ¡®i¥Ü±qÀÉ®×¹ï¸Ü¤è¶ô©Ò©ì¨ÓªºÀɮצWºÙ¡C

­n«Ø¥ß¤@­Ó¥i·í§@Àɮשì©ñ¨Ó·½ªºÀ³¥Îµ{¦¡¤]¤£§xÃø¡C±z¥u¶·§âÀÉ®×¥[¤J¨ìÀɮ׶°¦X¤¤¡A¨Ã¥B³]©w¬°vbCFFiles«¬ºA¡C½Ð°O±o¡A¥Ø¼Ðª«¥ó»Ý­nÀɮ׶°¦X¤¤¦s©ñªº¬OÀɮצWºÙ¥H¤Î§¹¾ãªºÀɮ׸ô®|¡C©³¤Uªºµ{¦¡§i¶D±z¦p¦ó§âFileListBox±±¨î¶µ·í§@©ì¦²§@·~ªº¨Ó·½¡G

Private Sub File1_OLEStartDrag(Data As DataObject, AllowedEffects As Long)
    Dim i As Integer, path As String
    path = File1.path & IIf(Right$(File1.path, 1) <> "\", "\", "")
    ' Add all selected files to the Data.Files collection.
    Data.Files.Clear
    For i = 0 To File1.ListCount - 1
        If File1.Selected(i) Then
            Data.Files.Add path & File1.List(i)
        End If
    Next
    If Data.Files.Count Then
        ' Only if we actually added files
        Data.SetData , vbCFFiles
        AllowedEffects = vbDropEffectCopy
    End If
End Sub

¨Ï¥Î¦Û­qªº®æ¦¡
¡@

¹ê»Ú¤WOLE©ì©ñ¾÷¨î¥iµo´§¤ñµ§ªÌ©Ò¥Ü½d¹L§ó¨ã¼u©Êªºµ{¦¡¡A¥¦¤]¥i¤ä´©¦Û­qªº®æ¦¡¡CÁ|¨Ò¨Ó»¡¡A±z¥i¯à»Ý­n¤@­Óªí³æ¯àÅã¥Üµo²¼¡B­q³æ©Î¬O«È¤áªº¸ê®Æ¡A¦Ó±z§Æ±æ¨ã¦³Åý¨Ï¥ÎªÌ¥i±q¨ä¥Lªí³æ©ì¦²³o¨Ç¸ê®Æªº¯à¤O¡C¨Ï¥Î¦Û­qªº®æ¦¡¤]¥i¥H»´ÃPªºÅý±z¦b¤£¦PªºÀ³¥Îµ{¦¡¹êÅ餤Âà´«¸ê°T¡A¦Ó¦P®ÉÁקK±¼¤£¤p¤ß±N¸ê®Æ©ñ¨ì¨ä¥Lªºµ{¦¡¤¤¡C¨Ï¥Î³o­Ó¤èªk¡A±z¥i¥H¦bÀ³¥Îµ{¦¡¶¡·h²¾¾÷±K©Êªº¸ê®Æ¡A¦Ó¤£¥Î¦Ò¼{³Q¥¼±ÂÅv¨Ï¥ÎªÌÀò¨úªº¦MÀI¡C

­n¨Ï¥Î¦Û­q®æ¦¡ªº²Ä¤@¨BÆJ¡A´N¬O¥ý¦bWindows¤¤µù¥U¡A±z¥i¥H©I¥sRegisterClipboardFormat API¨ç¦¡¨Ó¹F¦¨¡C¨C¤@­Ó¨Ï¥Î¨ì¦Û­q®æ¦¡¸ê®ÆªºÀ³¥Îµ{¦¡³£¥²¶·­n¦³³o­Ó¨BÆJ¡CWindows«OÃÒ·í²Ä¤@¦¸©I¥s¨Ã¶Ç¤J¦Û­q®æ¦¡¦WºÙ(¦p¤U­±µ{¦¡¤¤ªº PersonalData)µ¹³o­Ó¨ç¦¡®É¡A·|¶Ç¦^¤@­Ó°ß¤@(unique)ªº¾ã¼Æ­È¡A¦ÓÀH«á§Q¥Î³o­Ó®æ¦¡¦WºÙ·í°Ñ¼Æ¨Ó©I¥s³o­ÓAPI¨ç¦¡®É·|¶Ç¦^¦P¼Ëªº­È¡A¬Æ¦Ü±q¤£¦PªºÀ³¥Îµ{¦¡¤¤©I¥s³o­Ó¨ç¦¡¶Ç¦^ªº­È¤]¬O¤@¼Ëªº¡C

Private Declare Function RegisterClipboardFormat Lib "user32" _
    Alias "RegisterClipboardFormatA" (ByVal lpString As String) As Integer
Dim CustomFormat As Integer

Private Sub Form_Load()
    CustomFormat = RegisterClipboardFormat("PersonalData")
End Sub

¦¹®É¡A ±z¥i±N¸ê®Æ¥ÎCustomFormat ÃѧO¦r¦s°_¨Ó¡A«ê¦n¸ò¼Ð·Ç®æ¦¡¦pvbCFText ©Î vbCFBitmap°µªk¬Û¦P¡C°ß¤@¤£¦Pªº¬O¡A¦Û­q¸ê®Æ®æ¦¡¦b¶Ç°e¨ìDataObject.SetData ¤èªk«e¡A¥²¶·¥ý¸ü¤J¨ìByte°}¦C¡C¹Ï9-22ªº¥Ü½dµ{¦¡¨Ï¥Î³o­Ó§Þ¥©¦b¨â­Óªí³æ¶¡·h²¾¤Î½Æ»s¸ê®Æ¡G

' Code in the source application
Private Sub imgDrag_OLESetData(Data As DataObject, DataFormat As Integer)
    Dim i As Integer, text As String, bytes() As Byte
    ' Build a long string made up of field contents.
    For i = 0 To txtField.UBound
        If i > 0 Then text = text & vbNullChar
        text = text & txtField(i)
    Next
    ' Move to a byte array, and then assign it to DataObject.
    bytes() = text
    Data.SetData bytes(), CustomFormat
End Sub


¡@

¹Ï9-22 ±z¥i¥H¦b¤£¦Pªí³æ¡A¬Æ¦Ü¦b¤£¦PªºÀ³¥Îµ{¦¡¹êÅ鶡·h²¾¦Û­q®æ¦¡ªº¸ê®Æ¡A¦Ó¤£¥Î¾á¤ß§â¾÷±K¸ê®Æ¤£¤p¤ß©ñ¨ì¨ä¥Lªº¦a¤è¡C

¥Ø¼Ðªí³æ¥²¶·¨ú¥X Byte°}¦C¡A±N¥¦­ÌÁ٭즨­ì¨Óªº¦r¦ê¡A¨Ã¥B©ñ¨ì¦U¦ÛªºÄæ¦ì¤¤¡G

' Code in the target application
Private Sub imgDrag_OLEDragDrop(Data As DataObject, Effect As Long, _
    Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim bytes() As Byte, text() As String, i As Integer
    bytes() = Data.GetData(CustomFormat)
    ' Retrieve individual values, and then assign them to fields.
    text() = Split(CStr(bytes), vbNullChar)
    For i = 0 To txtField.UBound
        txtField(i) = text(i)
    Next
End Sub

±z¥i¥HÂsÄý¦b¡AÀH®Ñ¥úºÐ¤¤ªº­ì©lµ{¦¡½X¡A¨ú±o§ó¦hÃö©ó³o¶µ§Þ¥©ªº¸ê°T¡C

²{¦b±z¤w´x´¤¤F¦³ÃöSDI¤ÎMDIªí³æ¡B¹ï¸Ü¤è¶ô¡BOLE©ì©ñªº§Þ¥©¡A¨Ã§ó²`¤JÁA¸Ñ¸û½ÆÂøªºVisual Basic¥~³¡ActiveX±±¨î¶µ°µ¦n¤F·Ç³Æ¡C±µ¤U¨Óªº¤T³¹±N±´°Q³o¨Ç¥~³¡ActiveX±±¨î¶µ¡C