flyingleaf's blog

象外行一样思考,象专家一样实践。

添加BitMap到Menu

coolbean | 29 八月, 2007 05:12

在Window API中,有一些名词要先清楚,假设有一功能表如下:

档案   编辑 选项  --> hMenu    (功能表)
      +-------+
      |复制   |---------> hSubMenu (子功能表)
      |贴上   |
      |减下 -------------> MenuID   (功能表项目)
      |       |
      +-------+

如果,我们使用vb的功能表编辑器做出上面的Menu,那 hMenu的取得使用GetMenu() API
,而hSubMenu 的取得是 GetSubMenu,而GetSubMenu()的第二个叁数指的是功能表的第
几个子功能表,以上例来说,编辑子功能表是第1个子功能表(以0为基准),所以编辑子
功能表的取得应用以下的呼叫 :

hMenu = GetMenu(Me.hwnd)
hSubMenu = GetSubMenu(hMenu, 1) '取得编辑子功能表的hSubMenu

而功能表项目则由以下的呼叫取得,第二叁数指的是该子功能表的第几个项目(以0
开始),故复制 功能表项目 = 0  减下 = 2

MenuId = GetMenuItemID(hSubMenu, 0) '取得复制 的hMenuId

接着便是以ModifyMenu来更动MenuId成BitMap的方式

Set Pic1 = LoadPicture("E:cli.bmp")
ModifyMenu hSubMenu, 0, MF_BITMAP Or MF_BYPOSITION, MenuId, pic1.Handle

ModifyMenu 第二个叁数  表示更动hSubMenu所指的子功能表中第几个功能表项目
   第三个叁数  MF_BITMAP 表示用BitMap的方式显示
       MF_STRING 表示用字串方式显示
       MF_BYPOSITION 表示第二个叁数的值代表是依位置来算
   第四个叁数  MenuId
   第五个叁数  显示图的hBitMap

另外,如何做到MenuItem的左方有一小Bitmap,右方仍是字串呢,使用以下的API

SetMenuItemBitmaps(

    hSubMenu as Long ,    // handle of 子功能表
    uItem    as Long ,    // 更动第几个Menu Item
    fuFlags as Long,    // menu item flags
    hbmUnchecked as Long,  // handle of unchecked bitmap
    hbmChecked as Long    // handle of checked bitmap
   )

Set Pic2 = LoadPicture("e:cli2.BitMap")

Call SetMenuItemBitmaps(hSubMenu, 1, MF_BYPOSITION,pic2.Handle, Pic2.Handle)

这里有一个地方要特别注意,到底hbmUnchecked/hbmchecked 所指的BitMap图有多大呢,
如果pic2所放入的BitMap太大,那不会出现我们想要的图,那得自己想办法缩图;而使
用以下的API可以取得Menu Item左边Bitmap图的大小(By Pixels)

i = GetMenuCheckMarkDimensions
wd5 = i Mod 2 ^ 16  '宽
hi5 = i / 2 ^ 16    '高

而我们Load进来的图之宽 Me.ScaleX(pic2.Width, vbHimetric, vbPixels)
    高 Me.ScaleY(pic2.Height, vbHimetric, vbPixels)

於是呢,我写了一个GetBitMapHandle 来取得hbmUnchecked/hbmchecked所需的BitMap
Handle,而且该hBitMap所指的图,大小刚好是系统内定的大小,而不必在乎原始的图
有多大,当然了,一定要使用BitMap图,不可使用icon/gif等之类的图,这是什麽原
因呢,这是因为我使用StdPicture物件来开启图形档,如果图形档是BitMap图,那麽,
stdPicture物件的Handle属性便是hBitmap。
而要看得懂我GetBitMapHandle的程式,首先请先查阅我另一篇文章Memory Dc与hBitmap
 (查看全文)

VB:如何监听打开的窗口和程序

coolbean | 29 八月, 2007 04:15

         这个问题是CSDN网友MattHgh (黎明破晓前)提出来的,这个问题其实有很多种解决的办法,这里我用WH_SHELL钩子解决,WH_SHELL钩子可以获得很多信息,比如窗口创建、窗口销毁、窗口被激活、窗口的标题栏被重绘等等,但是这些信息都是基于窗口的,而MattHgh 希望同时获得相应的程序。那么怎么根据窗口的句柄的句柄获得对应的程序路径呢,这个当然可以通过枚举所有的进程获得,不过这样一来,速度就慢上一些了,我在程序中用到的是另外一种方法,这种方法尽管很平常,但我估计有些朋友可能还不知道,所以下面我用程序简单的说明一下:

'根据窗口句柄获取对应的程序路径,只适用于NT平台
Public Function GetEXEFromHandle(Optional ByVal nHWnd As Long = 0) As String
    Dim nProcID As Long
    Dim nResult As Long
    Dim nTemp As Long
    Dim lModules(1 To 200) As Long
    Dim sFile As String
    Dim hProcess As Long  '
    If nHWnd = 0 Then nHWnd = GetForegroundWindow()
    '获得窗口的ProcessID
    If GetWindowThreadProcessId(nHWnd, nProcID) <> 0 Then
        '打开Process,获得窗口对应的进程句柄
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or _
        PROCESS_VM_READ, 0, nProcID)
        If hProcess <> 0 Then
            ' 获得窗口对应的Module
            nResult = EnumProcessModules(hProcess, lModules(1), _
              200, nTemp)
            If nResult <> 0 Then
                 '获得程序名
                sFile = Space$(260)
                nResult = GetModuleFileNameEx(hProcess, 0, sFile, Len(sFile))
                sFile = LCase$(Left$(sFile, nResult))
                GetEXEFromHandle = sFile
            End If
            '关闭Process
            CloseHandle hProcess
        End If
    End If
End Function

        请注意函数开始时的注释,这种方法只适用于NT平台,所以用win9x的朋友还是老老实实的枚举进程吧,这样的代码在网上很容易找到,这里我就不罗嗦了。
        下面说说WH_SHELL钩子,MSDN上对这个钩子的描述是这样的:

 (查看全文)

文本操作快捷键,VB6.0 默认快捷键选项

coolbean | 29 八月, 2007 01:02

下列快捷组合键可在文本编辑器中用于在打开的文档中删除、移动或者格式化文本。

命令 快捷键 说明

编辑.分行

Enter Shift + Enter

插入一个新行。

编辑.折叠到定义

Ctrl + M,Ctrl + O

自动确定在代码中创建区域(如过程)的逻辑边界,然后隐藏它们。

编辑.注释选定内容

Ctrl + K,Ctrl + C

使用编程语言的正确注释语法将代码的当前行标记为注释。

编辑.删除水平空白

Ctrl + K,Ctrl +

折叠选定内容中的空白,如果没有选定内容,则删除与光标相邻的空白。

编辑.编排文档格式

Ctrl + K,Ctrl + D

按“选项”对话框“文本编辑器”部分中的语言的“格式设置”窗格中的指定,应用该语言的缩进和空格格式设置。

编辑.格式化选定内容

Ctrl + K,Ctrl + F

根据周围的代码行,正确缩进选定的代码行。

编辑.隐藏选定内容

Ctrl + M,Ctrl + H

隐藏选定文本。信号图标标记隐藏文本在文件中的位置。

编辑.插入制表符

Tab

将文本行缩进指定数量的空格,如 5 个。仅在 .NET Framework 设计器中可用。

编辑.剪切行

Ctrl + Y

将选择的所有行(或当前行,如果未选择任何行)剪切到剪贴板。

编辑.删除行

Ctrl + Shift + Y

删除所有选定行或当前行(如果没有选定行)。

编辑.上开新行

Ctrl + Enter

在插入点之上插入一个空行。

编辑.下开新行

Ctrl + Shift + Enter

在插入点之下插入一个空行。

编辑.行转置

Shift + Alt + T

将包含插入点的行移动到下一行之下。

编辑.改写模式

Insert

改写文档中已有的字符,而不是插入字符。仅在文本编辑器中可用。

编辑.停止隐藏当前区域

Ctrl + M,Ctrl + U

移除当前选定区域的大纲显示信息。

编辑.停止大纲显示

Ctrl + M,Ctrl + P

从整个文档中移除所有大纲显示信息。

编辑.交换定位点

Ctrl + R,Ctrl + P

交换当前选定内容的定位点与结束点。

编辑.左缩进

Shift + Tab

将选定行左移一个制表位。仅在 .NET Framework 设计器中可用。

编辑.切换所有大纲显示

Ctrl + M,Ctrl + L

在隐藏和显示状态之间切换所有以前被标记为隐藏的文本部分。

编辑.切换书签

Ctrl + K,Ctrl + K

在当前行处设置或移除书签。

编辑.切换大纲显示展开

Ctrl + M,Ctrl + M

在隐藏和显示状态之间切换当前选定的隐藏文本部分。

编辑.切换任务列表快捷方式

Ctrl + K,Ctrl + H

在当前行处设置或移除快捷方式。

编辑.取消注释选定内容

Ctrl + K,Ctrl + U

从代码的当前行中移除注释语法。

编辑.查看空白

Ctrl + R,Ctrl + W

显示或隐藏空格和制表符标记。

编辑.字转置

Ctrl + Shift + T

对调插入点两边的单词。

视图.显示引用

Alt + F12

执行区分大小写的全字符号搜索并在“查找符号结果”窗口中显示结果。

 
Accessible and Valid XHTML 1.0 Strict and CSS
Powered by LifeType - Design by BalearWeb