<address id="xpjh9"><listing id="xpjh9"><meter id="xpjh9"></meter></listing></address>

<address id="xpjh9"><address id="xpjh9"><listing id="xpjh9"></listing></address></address>
<noframes id="xpjh9">
<noframes id="xpjh9">

<address id="xpjh9"><address id="xpjh9"><listing id="xpjh9"></listing></address></address>
    <form id="xpjh9"></form><address id="xpjh9"><listing id="xpjh9"><menuitem id="xpjh9"></menuitem></listing></address>

      <noframes id="xpjh9">
      VB.net 2010 視頻教程 VB.net 2010 視頻教程 VB.net 2010 視頻教程
      SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
      當前位置:
      首頁 > 編程開發 > VBnet >
      • vb.net教程之Visual Basic 6子類化的實現

      • 2015-01-24 13:32 來源:未知
      Visual Basic 6子類化的實現(相關vb.net教程)
      在Visual Basic 6子類化的實現中我們將通過一段代碼的實例來介紹這一技術在VB6中的應用。現在很多開發社區中經常談到的一個話題就是界面開發如何Skin,這種技術有很多解決方式,如使用可以貼圖的控件或使用第三方開發的換膚ActiveX控件。其實Skin技術需要處理的是WM_DRAWITEM、WM_MEASUREITEM、WM_NCPAINT消息,這些消息的主要用途就是可以重畫控件和窗口的非客戶區。想要對這些VB6無法處理的消息進行編程就必須用到子類化,這些消息都會被發送到能夠自繪的控件的窗口上,因此下面的例子就是利用窗口子類化來重畫Button控件。
      ①創建工程
      啟動Visual Basic 6同時創建一個標準EXE工程。
      ②窗口布局
      在FORM1上放置3個Button控件,并將前兩個Button的Style屬性設置為1-Graphical,因為只有Style屬性設置為Graphical的Button才可以Owner-drawn。
      ③在窗體中錄入代碼
      Private Sub Command3_Click()
          '通過Enabled屬性的控制,來顯示重畫控件在Unenabled狀態時的效果
          If Command1.Enabled Then
              Command1.Enabled = False
          Else
              Command1.Enabled = True
          End If
      End Sub
       
      Private Sub Form_Load()
          '安裝子類化入口
          Call Init(Me.hWnd)
      End Sub
       
      Private Sub Form_Unload(Cancel As Integer)
          '卸載子類化
          Call Terminate(Me.hWnd)
      End Sub
      ④加入一個模塊并錄入代碼
      Option Explicit
      ' -- 引用Win32Api –
      '得到默認的窗口消息處理過程的地址需要的API
      Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
      '設置一個新的窗口消息處理過程的地址需要的API
      Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
      '給指定的窗口消息處理過程傳遞消息需要的API
      Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
      '內存拷貝
      Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
      Const GWL_WNDPROC = (-4&)
      Dim PrevWndProc&
      Private Const WM_DESTROY = &H2
      Private Const WM_DRAWITEM = &H2B
      Private Type RECT
          Left As Long
          Top As Long
          Right As Long
          Bottom As Long
      End Type
      'WM_DRAWITEM需要處理的結構體
      Private Type DRAWITEMSTRUCT
          CtlType As Long
          CtlID As Long
          itemID As Long
          itemAction As Long
          itemState As Long
          hwndItem As Long
          hdc As Long
          rcItem As RECT
          itemData As Long
      End Type
      ' Owner draw 常量
      Private Const ODT_BUTTON = 4
      ' Owner draw 動作
      Private Const ODA_DRAWENTIRE = &H1
      Private Const ODA_SELECT = &H2
      Private Const ODA_FOCUS = &H4
      ' Owner draw 狀態
      Private Const ODS_SELECTED = &H1
      Private Const ODS_GRAYED = &H2
      Private Const ODS_DISABLED = &H4
      Private Const ODS_CHECKED = &H8
      Private Const ODS_FOCUS = &H10
      '得到指定窗口的文本
      Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
      'GDI相關API函數,重畫Button時使用
      Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
      Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
      Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
      Private Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
      '色彩常量
      Const COLOR_SCROLLBAR = 0
      Const COLOR_BACKGROUND = 1
      Const COLOR_ACTIVECAPTION = 2
      Const COLOR_INACTIVECAPTION = 3
      Const COLOR_MENU = 4
      Const COLOR_WINDOW = 5
      Const COLOR_WINDOWFRAME = 6
      Const COLOR_MENUTEXT = 7
      Const COLOR_WINDOWTEXT = 8
      Const COLOR_CAPTIONTEXT = 9
      Const COLOR_ACTIVEBORDER = 10
      Const COLOR_INACTIVEBORDER = 11
      Const COLOR_APPWORKSPACE = 12
      Const COLOR_HIGHLIGHT = 13
      Const COLOR_HIGHLIGHTTEXT = 14
      Const COLOR_BTNFACE = 15
      Const COLOR_BTNSHADOW = 16
      Const COLOR_GRAYTEXT = 17
      Const COLOR_BTNTEXT = 18
      Const COLOR_INACTIVECAPTIONTEXT = 19
      Const COLOR_BTNHIGHLIGHT = 20
      Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
      Private Declare Function FrameRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
      Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
      '畫筆格式
      Const PS_SOLID = 0
      Const PS_DASH = 1 ' -------
      Const PS_DOT = 2 ' .......
      Const PS_DASHDOT = 3 ' _._._._
      Const PS_DASHDOTDOT = 4 ' _.._.._
      Const PS_NULL = 5
      Const PS_INSIDEFRAME = 6
      Const PS_USERSTYLE = 7
      Const PS_ALTERNATE = 8
      Const PS_STYLE_MASK = &HF
      Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long
      Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
      Private Type POINTAPI
          x As Long
          y As Long
      End Type
      Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
      Private Const DT_SINGLELINE = &H20
      Private Const DT_CENTER = &H1
      Private Const DT_VCENTER = &H4
      Private Declare Function SetTextColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
      Private Declare Function SetBkMode Lib "gdi32" (ByVal hdc As Long, ByVal nBkMode As Long) As Long
      Private Const TRANSPARENT = 1
      ' – 聲明結束 --
      Private Sub DrawButton(ByVal hWnd As Long, ByVal hdc As Long, rct As RECT, ByVal nState As Long)
          Dim P As POINTAPI
          Dim s As String
          Dim hbr As Long
          Dim hpen As Long
       
          hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)) '獲得按鈕的背景顏色RGB(231, 231, 231)
          SelectObject hdc, hbr  '選擇使用刷子
          FillRect hdc, rct, hbr
          DeleteObject hbr
       
          '畫文字時背景為透明狀
          SetBkMode hdc, TRANSPARENT
          '得到Button的Caption
          s = String$(255, " ")
          GetWindowText hWnd, s, 255
          s = Trim$(s)
          '根據Button的Enabled狀態進行重畫
          If (nState And ODS_DISABLED) = ODS_DISABLED Then
              '畫外圍灰框
              hbr = CreateSolidBrush(RGB(132, 130, 132))
              SelectObject hdc, hbr
              FrameRect hdc, rct, hbr
              DeleteObject hbr
              '畫內側3D效果->亮色
              hpen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255))
              SelectObject hdc, hpen
              MoveToEx hdc, rct.Left + 1, rct.Top + 1, P
              LineTo hdc, rct.Right - 1, rct.Top + 1
              MoveToEx hdc, rct.Left + 1, rct.Top + 1, P
              LineTo hdc, rct.Left + 1, rct.Bottom - 1
              DeleteObject hpen
              '畫內側3D效果->暗色
              hpen = CreatePen(PS_SOLID, 1, RGB(189, 190, 189))
              SelectObject hdc, hpen
              MoveToEx hdc, rct.Left + 1, rct.Bottom - 2, P
              LineTo hdc, rct.Right - 1, rct.Bottom - 2
              MoveToEx hdc, rct.Right - 2, rct.Top + 1, P
              LineTo hdc, rct.Right - 2, rct.Bottom - 1
              DeleteObject hpen
              '畫陰影文字
              rct.Left = rct.Left + 1
              rct.Right = rct.Right + 1
              rct.Bottom = rct.Bottom + 1
              rct.Top = rct.Top + 1
              SetTextColor hdc, GetSysColor(COLOR_BTNHIGHLIGHT)
              DrawText hdc, s, LenB(StrConv(s, vbFromUnicode)), rct, DT_CENTER Or DT_SINGLELINE Or DT_VCENTER
              rct.Left = rct.Left - 1
              rct.Right = rct.Right - 1
              rct.Bottom = rct.Bottom - 1
              rct.Top = rct.Top - 1
              SetTextColor hdc, GetSysColor(COLOR_GRAYTEXT)
              DrawText hdc, s, LenB(StrConv(s, vbFromUnicode)), rct, DT_CENTER Or DT_SINGLELINE Or DT_VCENTER
              Exit Sub
          End If
          '按下Button時重畫
          If (nState And ODS_SELECTED) = ODS_SELECTED Then
              '畫內部區域顏色
              hbr = CreateSolidBrush(RGB(156, 186, 222))
              SelectObject hdc, hbr
              FillRect hdc, rct, hbr
              DeleteObject hbr
              '畫外圍灰框
              hbr = CreateSolidBrush(RGB(99, 125, 165))
              SelectObject hdc, hbr
              FrameRect hdc, rct, hbr
              DeleteObject hbr
              '畫內側3D效果->亮色
              hpen = CreatePen(PS_SOLID, 1, RGB(123, 158, 206))
              SelectObject hdc, hpen
              MoveToEx hdc, rct.Left + 1, rct.Top + 1, P
              LineTo hdc, rct.Right - 1, rct.Top + 1
              MoveToEx hdc, rct.Left + 1, rct.Top + 1, P
              LineTo hdc, rct.Left + 1, rct.Bottom - 1
              DeleteObject hpen
              '畫內側3D效果->暗色
              hpen = CreatePen(PS_SOLID, 1, RGB(181, 203, 231))
              SelectObject hdc, hpen
              MoveToEx hdc, rct.Left + 1, rct.Bottom - 2, P
              LineTo hdc, rct.Right - 1, rct.Bottom - 2
              MoveToEx hdc, rct.Right - 2, rct.Top + 1, P
              LineTo hdc, rct.Right - 2, rct.Bottom - 1
              DeleteObject hpen
       
              rct.Left = rct.Left + 1
              rct.Right = rct.Right + 1
              rct.Bottom = rct.Bottom + 1
              rct.Top = rct.Top + 1
              SetTextColor hdc, GetSysColor(COLOR_BTNTEXT)
              DrawText hdc, s, LenB(StrConv(s, vbFromUnicode)), rct, DT_CENTER Or DT_SINGLELINE Or DT_VCENTER
              Exit Sub
          End If
          'Button得到焦點時重畫
          If (nState And ODS_FOCUS) = ODS_FOCUS Then
              '畫內部區域顏色
              hbr = CreateSolidBrush(RGB(173, 203, 239))
              SelectObject hdc, hbr
              FillRect hdc, rct, hbr
              DeleteObject hbr
              '畫外圍灰框
              hbr = CreateSolidBrush(RGB(107, 138, 181))
              SelectObject hdc, hbr
              FrameRect hdc, rct, hbr
              DeleteObject hbr
              '畫內側3D效果->亮色
              hpen = CreatePen(PS_SOLID, 1, RGB(198, 223, 247))
              SelectObject hdc, hpen
              MoveToEx hdc, rct.Left + 1, rct.Top + 1, P
              LineTo hdc, rct.Right - 1, rct.Top + 1
              MoveToEx hdc, rct.Left + 1, rct.Top + 1, P
              LineTo hdc, rct.Left + 1, rct.Bottom - 1
              DeleteObject hpen
              '畫內側3D效果->暗色
              hpen = CreatePen(PS_SOLID, 1, RGB(132, 174, 222))
              SelectObject hdc, hpen
              MoveToEx hdc, rct.Left + 1, rct.Bottom - 2, P
              LineTo hdc, rct.Right - 1, rct.Bottom - 2
              MoveToEx hdc, rct.Right - 2, rct.Top + 1, P
              LineTo hdc, rct.Right - 2, rct.Bottom - 1
              DeleteObject hpen
       
              SetTextColor hdc, GetSysColor(COLOR_BTNTEXT)
              DrawText hdc, s, LenB(StrConv(s, vbFromUnicode)), rct, DT_CENTER Or DT_SINGLELINE Or DT_VCENTER
          Else
              '畫外圍灰框
              hbr = CreateSolidBrush(RGB(132, 130, 132))
              SelectObject hdc, hbr
              FrameRect hdc, rct, hbr
              DeleteObject hbr
              '畫內側3D效果->亮色
              hpen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255))
              SelectObject hdc, hpen
              MoveToEx hdc, rct.Left + 1, rct.Top + 1, P
              LineTo hdc, rct.Right - 1, rct.Top + 1
              MoveToEx hdc, rct.Left + 1, rct.Top + 1, P
              LineTo hdc, rct.Left + 1, rct.Bottom - 1
              DeleteObject hpen
              '畫內側3D效果->暗色
              hpen = CreatePen(PS_SOLID, 1, RGB(189, 190, 189))
              SelectObject hdc, hpen
              MoveToEx hdc, rct.Left + 1, rct.Bottom - 2, P
              LineTo hdc, rct.Right - 1, rct.Bottom - 2
              MoveToEx hdc, rct.Right - 2, rct.Top + 1, P
              LineTo hdc, rct.Right - 2, rct.Bottom - 1
              DeleteObject hpen
              '畫文字
              SetTextColor hdc, GetSysColor(COLOR_BTNTEXT)
              DrawText hdc, s, LenB(StrConv(s, vbFromUnicode)), rct, DT_CENTER Or DT_SINGLELINE Or DT_VCENTER
          End If
      End Sub
      '新的窗口消息處理過程,將被插入到默認處理過程之前
      Private Function SubWndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
          Dim di As DRAWITEMSTRUCT
          If Msg = WM_DESTROY Then Terminate (hWnd)
          '處理自畫消息
          If Msg = WM_DRAWITEM Then
              CopyMemory di, ByVal lParam, Len(di)
              '判斷是自畫Button
              If di.CtlType = ODT_BUTTON Then
                  DrawButton di.hwndItem, di.hdc, di.rcItem, di.itemState
                  '不返回VB的默認Button繪制過程
                  SubWndProc = 1
                  Exit Function
              End If
          End If
          '調用默認的窗口處理過程
          SubWndProc = CallWindowProc(PrevWndProc, hWnd, Msg, wParam, lParam)
      End Function
      '子類化入口
      Public Sub Init(hWnd As Long)
          PrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf SubWndProc)
      End Sub
      '子類化出口
      Public Sub Terminate(hWnd As Long)
          Call SetWindowLong(hWnd, GWL_WNDPROC, PrevWndProc)
      End Sub
      ' -- 模塊結束 -- '
       
      ⑤運行結果
      現在我們比較一下傳統式樣Button和新新式樣Button的區別吧,這個例子雖然代碼很多,而且用到了一些GDI函數,但是子類化技術實際上只需要Init、Terminate、SubWndProc三個函數,因為我們處理了較復雜的重畫操作,所以樣例看上去很長。

      需要指出的是不正確的子類化是非常危險的,將導致一個General Protection Fault(GPF)錯誤,致使VB應用立即崩潰。
        下面的例子將演示如何將About加入窗口的系統菜單。
      ①創建工程
      啟動Visual Basic 6同時創建一個標準EXE工程。
      ②在窗體中錄入代碼
      Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal bRevert As Long) As Long
      Private Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As String) As Long
       
      Private Const MF_BYCOMMAND = &H0&
      Private Const MF_BYPOSITION = &H400&
      Private Const MF_STRING = &H0&
      Private Const MF_SEPARATOR = &H800&
       
      Private Sub Form_Load()
       
          InsertMenu GetSystemMenu(Me.hWnd, False), 0, MF_BYPOSITION Or MF_SEPARATOR, 2001, ""
          InsertMenu GetSystemMenu(Me.hWnd, False), 0, MF_BYPOSITION Or MF_STRING, 2002, "About Me(&A)"
       
          '安裝子類化入口
          Call Init(Me.hWnd)
       
      End Sub
       
      Private Sub Form_Unload(Cancel As Integer)
       
          '卸載子類化
          Call Terminate(Me.hWnd)
       
      End Sub
      ③加入一個模塊并錄入代碼
      Option Explicit
       
      Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
      Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
       
      Const GWL_WNDPROC = (-4&)
      Const WM_DESTROY = &H2
       
      Dim PrevWndProc&
       
      Private Const WM_SYSCOMMAND = &H112
       
      Public Sub Init(hWnd As Long)
       
          '子類化入口
          PrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf SubWndProc)
       
      End Sub
       
      Public Sub Terminate(hWnd As Long)
       
          '子類化出口
          Call SetWindowLong(hWnd, GWL_WNDPROC, PrevWndProc)
       
      End Sub
       
      Private Function SubWndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
       
          '新的窗口消息處理過程,將被插入到默認處理過程之前
          If Msg = WM_DESTROY Then Terminate (Form1.hWnd)
          If wParam = 2002 Then
              MsgBox "About Context", vbInformation, "About..."
          End If
       
          '調用默認的窗口處理過程
          SubWndProc = CallWindowProc(PrevWndProc, hWnd, Msg, wParam, lParam)
      End Function
      ' -- 模塊結束 -- '
      相關教程
      江苏快3 泉州 | 甘南 | 南充 | 章丘 | 承德 | 浙江杭州 | 阿拉尔 | 伊犁 | 台南 | 克拉玛依 | 南平 | 吕梁 | 三河 | 大连 | 西双版纳 | 贵港 | 吐鲁番 | 乳山 | 河南郑州 | 焦作 | 菏泽 | 茂名 | 阳江 | 六安 | 兴安盟 | 澳门澳门 | 葫芦岛 | 甘孜 | 神木 | 长治 | 滁州 | 三沙 | 六盘水 | 防城港 | 揭阳 | 喀什 | 中卫 | 克孜勒苏 | 兴安盟 | 嘉兴 | 甘孜 | 曹县 | 香港香港 | 甘南 | 永州 | 福建福州 | 醴陵 | 六盘水 | 厦门 | 五家渠 | 靖江 | 招远 | 余姚 | 曲靖 | 香港香港 | 大理 | 固原 | 平潭 | 延边 | 任丘 | 乌兰察布 | 湘西 | 齐齐哈尔 | 云南昆明 | 渭南 | 海宁 | 深圳 | 项城 | 万宁 | 永州 | 南阳 | 宁波 | 鸡西 | 张掖 | 日喀则 | 扬中 | 澳门澳门 | 衡阳 | 遂宁 | 昆山 | 林芝 | 海南海口 | 阿克苏 | 桂林 | 湖北武汉 | 怒江 | 定西 | 阿拉善盟 | 沭阳 | 宁德 | 湖北武汉 | 海安 | 商丘 | 文昌 | 许昌 | 昭通 | 辽宁沈阳 | 安庆 | 库尔勒 | 广饶 | 临夏 | 塔城 | 汉中 | 如皋 | 乌兰察布 | 吉林 | 广饶 | 辽阳 | 雄安新区 | 渭南 | 韶关 | 平顶山 | 定州 |