WIN32 汇编 工具栏的使用

说起工具栏我们都不会陌生为了方便起见,首先看一下图:标示的地方就是工具栏,好像是一个一个的位图文件组成的一样,其实那就是位图组成的,只不过是一组连续在一起的位图(而且是windows自己定义好的,我们只管拿来使用就行了)。

对于工具栏的实现我大概分为如下几步:

资源文件
菜单 IDR_MENU1
图标 IDI_ICON1
字符串表 STRINGTABLE
   
程序源代码
改变工具栏大小     _Resize
消息处理过程 _ProcWinMain
窗口模板 主函数

_WinMain

下面来看一下编写资源文件的时候遇见的问题及心得体会:这次编写资源文件依然用的是ResEdit工具,还记得在编写状态栏的时候创建资源文件的时候创建的是一个对话框,然后在对话框中实现的状态栏,但是工具栏则不能在对话中发挥其所有功能,如果在对话框中使用工具栏则有一些工具栏的高级功能无法实现,因为当工具栏向父窗口发送WM_NOTIFY消息时,父窗口必须根据消息处理情况返回TRUE或FALSE,然后工具栏会根据,父窗口的不同返回值做出不同的动作,因此,如果没有返回值那么工具栏就无法完成正确的动作,然而对话框过程的返回值只会用来通知“对话框管理器”是否处理了相关消息,返回值并不会被对话框管理器返回到工具栏子窗口(工具栏也是一个子窗口)去,所以对话框中无法使用工具栏的高级功能(可以添加删除按钮),但是如果只是为了使用工具栏的按钮当做菜单快捷按钮的话可以使用对画框,因为此时只需要处理WM_COMMAND消息,此消息并不需要返回值。如果看罗云斌老师的资源文件的时候你会发现,资源文件里面其实也包含对话框文件,但是并没有使用,我感觉可以去掉(我写的时候就没写。。懒。。),此外关于资源文件就没有什么问题了。下面看一下资源文件代码:

// Generated by ResEdit 1.6.6

// Copyright (C) 2006-2015

// http://www.resedit.net

#include <windows.h>

#include <commctrl.h>

#include <richedit.h>

#include "resource.h"

//

// Menu resources

//

LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL

IDR_MENU1 MENU

{

POPUP "文件(&F)"

{

MENUITEM "新文件(N)...", IDM_NEW

MENUITEM "开文件(&O)...", IDM_OPEN

MENUITEM "保存文件(&S)", IDM_SAVE

MENUITEM SEPARATOR

MENUITEM "页面设置(&A)", IDM_PAGESETUP

MENUITEM "打印(&P)", IDM_PRINT

MENUITEM SEPARATOR

MENUITEM "退出(&X)", IDM_EXIT

}

POPUP "编辑(&E)"

{

MENUITEM "剪切(&U)", IDM_CUT

MENUITEM "拷贝(&C)", IDM_COPY

MENUITEM "粘贴(&P)", IDM_PASTE

MENUITEM SEPARATOR

MENUITEM "查找字符串(&S)", IDM_FIND

MENUITEM "替换字符串(&R)", IDM_REPLACE

}

POPUP "帮助(&H)"

{

MENUITEM "帮助(&H)", IDM_HELP

}

}

//

// String Table resources

//

LANGUAGE 1023, 63

STRINGTABLE

{

IDM_NEW                       "新建文件"

IDM_OPEN                      "打开文件"

IDM_SAVE                      "保存文件"

IDM_PAGESETUP                 "页面设置"

IDM_PRINT                     "打印"

IDM_COPY                      "拷贝"

IDM_CUT                       "剪切"

IDM_PASTE                     "粘贴"

IDM_FIND                      "查找"

IDM_REPLACE                   "替换"

IDM_HELP                      "帮助"

}

//

// Icon resources

//

LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL

IDI_ICON1          ICON           "F:\\ResEdit-win32\\23\\icon8.ico"

下面来看一下在编写实现工具栏的时候遇见的一些疑问及心得:

说实话在刚看到实现工具栏的字符提示功能和定制工具栏功能时,感觉太陌生了,好多的结构体,还有一些新的用法,当时头就大了,等你把每一个结构体每一个API函数搞懂以后再回过头来看一下,其实程序还是很简单的,只不过新的知识不少,其它的还是老生常谈的内容。在子函数_Resize中是为了改变工具栏的大小,然后在调节编辑区域的大小,改变工具栏的大小只需要向工具栏发送TB_AUTOSIZE消息就可以了,它会自动调节工具栏的大小,改变了工具栏的大小,也要适当的调整编辑区的大小,这个需要自己来实现,依然要涉及到GetClientRect和GetWindowRect这两个计算大小就要出现的烦人的函数(我在写状态栏的时候也仔细介绍过,还写了一篇关于这两个函数的博客,虽然不好理解,容易忘,但是多看看,多写写画画,还是可以理解记忆的),这个问题不再多说。

下面就是怎样在工具栏中显示提示字符串了,关于这个问题,我参考了一下书籍,当要显示工具提示信息时,工具提示控件(当创建工具栏的时候风格里包含TBSTYLE_TOOLTIPS的时候,CreateToolbarEx函数会自动创建一个工具提示控件Tool Tip 并为工具栏上的每个按钮注册提示文本,当鼠标指针移动到按钮上停留片刻的时候,工具栏提示信息会自动显示出来)向父窗口发送TTN_NEEDTEXT通知码(这个通知码是放在NMHDR结构中的,并且windows为每一个需要附带其他数据的WM_NOTIFY消息定义的不同的结构中都包含一个NMHDR结构),父窗口将需要显示的提示字符放在TOOLTIPTEXT结构中并返回以后,工具提示控件就会把它显示出来,首先将字符串包含在资源中,这时将TOOLTIPTEXT结构的hInst字段设置为字符串ID,其他字段保持为NULL,工具提示控件会自己使用LoadString函数装入字符串(这只使用的一中比较简便的方法,因为字符串ID和菜单的命令ID为一样的(一一对应)并且在NMHDR结构中的idFrom字段中返回了命令ID)如下代码:

.elseif  eax  ==  WM_NOTIFY                                       ;判断如果为工具栏发送的消息WM_NOTIFY

mov      ebx,lParam                              ;将WM_NOTIFY消息的lParam 地址传递给ebx

.if      [ebx + NMHDR.code] == TTN_NEEDTEXT       ;判断通知码是否为lParam指向的                                                                                                                  TOOLTIPTEXT结构中的NMHDR结构中的.code元素

assume   ebx:ptr TOOLTIPTEXT           ;将ebx设定为结构TOOLTIPTEXT的指针

mov      eax,[ebx].hdr.idFrom                ;将命令ID传递到eax

mov      [ebx].lpszText,eax                     ;把命令ID传递给TOOLTIPTEXT结构的lpszText                                                                                                        字段

push     hInstance                                    ;将包含字符串资源的模块句柄压栈

pop      [ebx].hInst                                    ;将包含字符串资源的模块句柄出栈并传递给                                                                                                                TOOLTIPTEXT结构中的hInst字段

assume  ebx:nothing                                ;取消开始的设定

上面就是显示提示字符的功能代码涉及到的一些陌生的结构,详细介绍一下.

下面就来介绍另一个比较有意思的功能:定制工具栏

什么叫定制工具栏?其实就是可以自定义的添加删除已经定义好的按钮(我自己的理解),说到定制工具栏那么首先应该想到的就是在用CreateToolbarEX函数创建工具栏的时候需要指定CCS_ADJUSTABLE风格(就如同窗口风格一样只不过是工具栏专属的风格),为了实现双击工具栏的空白处可以弹出一个可以添加自定义按钮的“自定义工具栏”,首先就需要知道通知码(包含在特定的结构体中)TBN_QUERYINSERT,TBN_QUERYDELETE,TBN_GETBUTTONINFO,从字面的意思就可以知道什么意思(英文),说道这几个通知码以及实现的功能,就需要知道另一个新的结构TBNOTIFY(具体内容看下面介绍),有一个问题就是怎么一会是这个结构一会又变成那个结构了(其实我自己感觉这样考虑比较好:对于那个NMHDR结构中在每个指定的结构中都会存在,而且NMHDR结构中的.code
通知码才是关键,首先判断通知码是什么,然后再根据不同的通知码指向不同的功能结构体,然后再做其它操作,这样理解就很容易理解了),下面就是怎么将在自定义窗口中将已经定义的按钮全部显示出来了:当通知码TBN_GETBUTTONINFO时,需要用到的结构体就是TBNOTIFY,看下面代码:

.elseif  [ebx + NMHDR.code] ==  TBN_GETBUTTONINFO              ;判断通知码是否为

                                                                                                                  TBN_GETBUTTONINFO

assume   ebx:ptr TBNOTIFY                            ;如果通知码是上面的,那么设置ebx为结构                                                                                                                      TBNOTIFY的指针

mov      eax,[ebx].item                                     ;将TBNOTIFY结构的Item字段传递给eax

.if      eax < NUM_BUTTONS                            ;比较按钮的索引值与NUM_BUTTONS的值(也就是16)

mov     ecx,sizeof TBBUTTON                     ;将TBBUTTTON结构的长度传递给ecx

              mul     ecx                                                     ;eax=eax*ecx

          add     eax,offset stToolbar                            ;eax就是下一个按钮内容的地址

invoke  RtlMoveMemory,addr [ebx].tbButton,eax,sizeof TBBUTTON    ;将以eax未开始地址的一段内                                                                                                  
                存 中的内容拷贝到[ebx].tbButton字段中

invoke  LoadString,hInstance,[ebx].tbButton.idCommand,addr @szBuffer,sizeof @szBuffer  ;将TBBUTTON结构中的idCommand字段拷贝到缓冲区@szBuffer中

lea     eax,@szBuffer                                         ;将缓冲区@szBuffer的内容传递给eax

mov     [ebx].pszText,eax                                  ;将eax的内容传递给TBNOTIFY结构的                                                                                                  
                          pszText字段(及按钮的提示字符串)

invoke  lstrlen,addr @szBuffer                         ;测量缓冲区的大小

mov     [ebx].cchText,eax                                  ;将缓冲区的大小(在eax中存放)传递给TNNOTIFY结                                                                                          
      构的cchText字段

          assume  ebx:nothing                                        
  ;取消设定(和开头的assume语句对应)

mov     eax,TRUE                                                  ;返回TRUE

ret                                                                          ;返回调用处

至此自定义工具栏的功能得以实现,一共出现了3个新的结构体在这里。下面看一下程序源代码:

                .386

.model flat, stdcall

option casemap :none

include         windows.inc

include         user32.inc

includelib      user32.lib

include         kernel32.inc

includelib      kernel32.lib

include         comctl32.inc

includelib      comctl32.lib

IDI_ICON1       equ      101

IDR_MENU1       equ      102

IDM_NEW         equ      40000

IDM_OPEN        equ      40001

IDM_SAVE        equ      40002

IDM_PAGESETUP   equ      40003

IDM_PRINT       equ      40004

IDM_COPY        equ      40005

IDM_CUT         equ      40006

IDM_PASTE       equ      40007

IDM_FIND        equ      40008

IDM_REPLACE     equ      40009

IDM_HELP        equ      40010

IDM_EXIT        equ      40011

ID_TOOLBAR      equ      1

ID_EDIT         equ      2

.data?

hInstance       dd       ?

hWinMain        dd       ?

hMenu           dd       ?

hWinToolbar     dd       ?

hWinEdit        dd       ?

.const

szClass         db       ‘EDIT‘,0

szClassName     db       ‘ToolbarExample‘,0

szCaptionMain   db       ‘工具栏示例‘,0

szCaption       db       ‘命令消息‘,0

szFormat        db       ‘收到 WM_COMMAND 消息,命令ID:%d‘,0

stToolbar       equ      this byte

TBBUTTON        <STD_FILENEW,IDM_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <STD_FILEOPEN,IDM_OPEN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <STD_FILESAVE,IDM_SAVE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>

TBBUTTON        <STD_PRINTPRE,IDM_PAGESETUP,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <STD_PRINT,IDM_PRINT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>

TBBUTTON        <STD_COPY,IDM_COPY,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <STD_CUT,IDM_CUT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <STD_PASTE,IDM_PASTE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>

TBBUTTON        <STD_FIND,IDM_FIND,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <STD_REPLACE,IDM_REPLACE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>

TBBUTTON        <STD_HELP,IDM_HELP,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>

TBBUTTON        <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>

NUM_BUTTONS     equ      16

.code

_Resize         proc

LOCAL    @stRect:RECT,@stRect1:RECT

invoke   SendMessage,hWinToolbar,TB_AUTOSIZE,0,0

invoke   GetClientRect,hWinMain,addr @stRect

invoke   GetWindowRect,hWinToolbar,addr @stRect1

mov      eax,@stRect1.bottom

sub      eax,@stRect1.top

mov      ecx,@stRect.bottom

sub      ecx,eax

invoke   MoveWindow,hWinEdit,0,eax,@stRect.right,ecx,TRUE

ret

_Resize endp

_ProcWinMain    proc     uses ebx edi esi hWnd ,uMsg,wParam,lParam

LOCAL    @szBuffer[128]:byte

mov      eax,uMsg

.if      eax  ==  WM_CLOSE

invoke   PostMessage,hWnd,WM_COMMAND,IDM_EXIT,0

.elseif  eax  ==  WM_CREATE

mov      eax,hWnd

mov      hWinMain,eax

invoke   CreateWindowEx,WS_EX_CLIENTEDGE,addr szClass,NULL,WS_CHILD or WS_VISIBLE or ES_MULTILINE or\

ES_WANTRETURN or WS_VSCROLL or ES_AUTOHSCROLL,0,0,0,0,hWnd,ID_EDIT,hInstance,NULL

mov      hWinEdit,eax

invoke   CreateToolbarEx,hWinMain,WS_VISIBLE or WS_CHILD or TBSTYLE_FLAT or TBSTYLE_TOOLTIPS or\

CCS_ADJUSTABLE,ID_TOOLBAR,0,HINST_COMMCTRL,IDB_STD_SMALL_COLOR,offset stToolbar,\

NUM_BUTTONS,0,0,0,0,sizeof TBBUTTON

mov      hWinToolbar,eax

call     _Resize                  ;注意此处作者用的是Call而并非是invoke

.elseif  eax  ==  WM_COMMAND

mov      eax,wParam

.if      ax  ==  IDM_EXIT

invoke  DestroyWindow,hWinMain

invoke  PostQuitMessage,NULL

.elseif  ax  !=  ID_EDIT

invoke  wsprintf,addr @szBuffer,addr szFormat,wParam

invoke  MessageBox,hWnd,addr @szBuffer,addr szCaption,MB_OK or MB_ICONINFORMATION

.endif

.elseif  eax  ==  WM_SIZE

call     _Resize

.elseif  eax  ==  WM_NOTIFY

mov      ebx,lParam

.if      [ebx + NMHDR.code] == TTN_NEEDTEXT

assume   ebx:ptr TOOLTIPTEXT

mov      eax,[ebx].hdr.idFrom

mov      [ebx].lpszText,eax

push     hInstance

pop      [ebx].hInst

assume  ebx:nothing

.elseif  ([ebx + NMHDR.code] == TBN_QUERYINSERT) || ([ebx + NMHDR.code] == TBN_QUERYDELETE)

mov      eax,TRUE

ret

.elseif  [ebx + NMHDR.code] ==  TBN_GETBUTTONINFO

assume   ebx:ptr TBNOTIFY

mov      eax,[ebx].iItem

.if      eax < NUM_BUTTONS

mov     ecx,sizeof TBBUTTON

mul     ecx

add     eax,offset stToolbar

invoke  RtlMoveMemory,addr [ebx].tbButton,eax,sizeof TBBUTTON

invoke  LoadString,hInstance,[ebx].tbButton.idCommand,addr @szBuffer,sizeof @szBuffer

lea     eax,@szBuffer

mov     [ebx].pszText,eax

invoke  lstrlen,addr @szBuffer

mov     [ebx].cchText,eax

assume  ebx:nothing

mov     eax,TRUE

ret

.endif

.endif

.else

invoke    DefWindowProc,hWnd,uMsg,wParam,lParam

ret

.endif

xor     eax,eax

ret

_ProcWinMain    endp

_WinMain proc

local @stWndClass:WNDCLASSEX

local @stMsg:MSG

invoke
InitCommonControls

invoke
GetModuleHandle,NULL

mov hInstance,eax

invoke
LoadMenu,hInstance,IDR_MENU1

mov hMenu,eax

invoke
RtlZeroMemory,addr @stWndClass,sizeof @stWndClass

invoke
LoadIcon,hInstance,IDI_ICON1

mov @stWndClass.hIcon,eax

mov @stWndClass.hIconSm,eax

invoke
LoadCursor,0,IDC_ARROW

mov @stWndClass.hCursor,eax

push hInstance

pop @stWndClass.hInstance

mov @stWndClass.cbSize,sizeof WNDCLASSEX

mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW

mov @stWndClass.lpfnWndProc,offset _ProcWinMain

mov @stWndClass.hbrBackground,COLOR_BTNFACE+1

mov @stWndClass.lpszClassName,offset szClassName

invoke
RegisterClassEx,addr @stWndClass

invoke
CreateWindowEx,NULL,\

offset szClassName,offset szCaptionMain,\

WS_OVERLAPPEDWINDOW,\

CW_USEDEFAULT,CW_USEDEFAULT,700,500,\

NULL,hMenu,hInstance,NULL

mov hWinMain,eax

invoke
ShowWindow,hWinMain,SW_SHOWNORMAL

invoke
UpdateWindow,hWinMain

.while
TRUE

invoke
GetMessage,addr @stMsg,NULL,0,0

.break
.if eax == 0

invoke
TranslateMessage,addr @stMsg

invoke
DispatchMessage,addr @stMsg

.endw

ret

_WinMain endp

start:

call _WinMain

invoke
ExitProcess,NULL

end        start

下面来介绍一下新的结构体和一些陌生的的API函数:

TBBUTTON        STRUCT

    iBitmap           DWORD    ?       ;按钮使用的位图编号

    idCommand   DWORD     ?       ;按钮按下时在WM_COMMAND中使用的ID

    fsState            BYTE          ?      ;按钮的状态

    fsStyle            BYTE          ?     ;按钮的风格

    _wPadl           WORD         ?       ;

    dwData           DWORD       ?      ;自定义数据

     iString           DWORD        ?      ;按钮字符串索引

TBBUTTON        ENDS

iBitmap

按钮图像的从零开始的索引。

idCommand

命令标识符相关的按钮。这个标识符中使用WM_COMMAND消息当按钮选择。

fsState

按钮状态标志。它可以结合下表中列出的值。

状态 描述

TBSTATE_CHECKED


按钮有TBSTYLE_CHECKED风格和被按下。


TBSTATE_ELLIPSES


按钮显示省略号(…)如果文本不符合大小的按钮。这种风格是独一无二的Windows CE嵌入。


TBSTATE_ENABLED


按钮接受用户输入。一个按钮没有这个国家不接受用户输入,并暗了下来。


TBSTATE_HIDDEN


按钮是不可见的,不能接收用户的输入。


TBSTATE_HIGHLIGHTED


突出显示的按钮。


TBSTATE_INDETERMINATE


这个按钮是暗了下来。


TBSTATE_PRESSED


这个按钮被按下。


TBSTATE_WRAP


后面的按钮有一个换行符。按钮也必须TBSTATE_ENABLED状态。

fsStyle

按钮的风格。它可以是一个按钮样式的组合中列出的值控制方式.

dwData

指定一个应用程序定义的值。

iString

按钮的从零开始的索引的字符串。

TBADDBITMAP            STRUCT

    hInst                          DWORD                 ?      ;包含位图的模块实例句柄

    nID                             DWORD                  ?      ;位图的资源ID

TBADDBITMAP            ENDS

hInst


处理模块实例可执行文件,它包含一个位图资源。您可以将系统定义的位图按钮添加到列表通过指定HINST_COMMCTRL hInst成员和成员以下值之一的国家免疫日。

价值 描述

IDB_STD_LARGE_COLOR


增加大,颜色标准的位图。


IDB_STD_SMALL_COLOR


添加小,颜色标准的位图。


IDB_VIEW_LARGE_COLOR


增加大,颜色查看位图。


IDB_VIEW_SMALL_COLOR


添加小,颜色查看位图。

nID

位图资源的资源标识符包含按钮图像。如果hInst为空,该参数必须包含按钮图像位图的句柄。

Windows CE头文件嵌入提供以下值作为标准和查看位图索引。

价值 描述

STD_COPY


指定复制图像。


STD_CUT


指定的图像。


STD_DELETE


指定删除图片。


STD_FILENEW


指定新文件的图像。


STD_FILEOPEN


指定打开的文件的图像。


STD_FILESAVE


指定保存文件的图像。


STD_FIND


指定找到图像。


STD_HELP


指定图像的帮助。


STD_PASTE


指定了粘贴图片。


STD_PRINT


指定打印图像。


STD_PRINTPRE


指定打印预览图像。


STD_PROPERTIES


指定属性的形象。


STD_REDOW


指定了重做形象。


STD_REPLACE


指定替代的形象。


STD_UNDO


指定了复原图像。


VIEW_DETAILS


指定视图细节图像。


VIEW_LARGEICONS


指定视图大图标形象。


VIEW_LIST


指定视图列表图片。


VIEW_SMALLICONS


指定视图小图标形象。


VIEW_SORTDATE


指定按日期排序的图像。


VIEW_SORTNAME


指定图像的名字。


VIEW_SORTSIZE


指定按大小排序的图像。


VIEW_SORTTYPE


指定排序类型的形象。

TOOLTIPTEXT     STRUCT

   hdr                      NMHDR        <>      ;头部位置是一个NMHDR结构

   lpszText             DWORD         ?      ; 工具提示字符串指针

   szText                 BYTE      80   dup (?)    ;工具提示字符串缓冲区

   hInst                    DWORD         ?           ;包含字符串资源的模块句柄

   uFlags                 DWORD          ?          ;标志

TOOLTIPTEXT       ENDS

TBNOTIFY             STRUCT

     hdr                     NMHDR       <>              ;头部也是一个NMHDR结构

    iTem                   DWORD        ?                ;按钮的位置索引

     tbButton            TBBUTTON    <>            ;包含按钮信息的TBBUTTON结构

     cchText              DWORD           ?             ;pszText中字符串的长度

     pszText              DWORD            ?            ;按钮的说明字符串

TBNOTIFY               ENDS       

下面看一下陌生的API函数

RtlMoveMemory()

功能:

从指定内存中复制内存至另一内存里.简称:复制内存,与CopyMemory相同

原型:

VOID RtlMoveMemory(

VOID UNALIGNED *Destination,

const VOID UNALIGNED *Source,

SIZE_T Length

);

参数:

Destination :指向移动目的地址的指针

Source :指向要复制的内存地址的指针

Length :指定要复制的字节数。

返回值:无

LoadString()

功能:


资源 里加载字符串资源到CString对象里。

原型:

WINUSERAPI int WINAPI LoadStringA(

__in_opt HINSTANCE hInstance,

__in UINT uID,

__out_ecount(cchBufferMax) LPSTR lpBuffer,

__in int nBufferMax);

参数:

参数1: hInstance是应用程序实例句柄。

参数2: uID是资源中的字符串编号。

参数3: lpBuffer是接收从资源里拷贝字符串出来的缓冲区。

参数4: nBufferMax是指明缓冲的大小。

返回值:

如果函数成功,返回值是TCHARs复制到缓冲区的数量,不包括终止NULL字符

CraeteToolbarEx()

功能:

这个函数创建一个工具栏窗口,并将指定的按钮添加到工具栏。

原型:

HWND CreateToolbarEx(

HWND hwnd,

DWORD ws,

UINT wID,

int nBitmaps,

HINSTANCE hBMInst,

UINT wBMID,

LPCTBBUTTON lpButtons,

int iNumButtons,

int dxButton,

int dyButton,

int dxBitmap,

int dyBitmap,

UINT uStructSize

);

参数:

hwnd

工具栏的父窗口句柄。

ws

在指定窗口工具栏风格。该参数必须指定至少WS_CHILD风格。

wID

工具栏的控制标识符。

nBitmaps

的按钮图像中包含指定的位图hBMInst wBMID。

hBMInst

处理模块实例包含位图资源的可执行文件。

wBMID

位图资源的资源标识符。如果hBMInst为空,该参数必须是一个有效的位图句柄。

lpButtons

长指向数组的指针TBBUTTON结构包含按钮添加到工具栏的信息。

iNumButtons

按钮添加到工具栏的数量。

dxButton

指定宽度,以像素为单位,按钮添加到工具栏。

dyButton

指定高度,以像素为单位的按钮添加到工具栏。

dxBitmap

指定宽度,以像素为单位,按钮添加到工具栏中的按钮图像。

dyBitmap

指定高度,以像素为单位的图像添加到工具栏中的按钮的按钮。

uStructSize

无符号整数包含TBBUTTON结构的大小。

返回值:

工具栏显示成功的窗口句柄。零表示失败

Lstrlen()

功能:

该函数返回指定字符串的字节长度(ANSI版)或字符长度(双字节标准版);其中不包括终止NULL字符。

原型:

int lstrlen(LPCTSTR lpString);

参数:

lpString:指向以NULL为终止符的字符串。

返回值:

指定字符串中字节(ANSI版)或字符(双字节标准版)的长度。

时间: 2024-10-04 07:36:57

WIN32 汇编 工具栏的使用的相关文章

二鸟学Win32 汇编——PE头文件

;代码段    .code;---------------------; 将内存偏移量RVA转换为文件偏移; lp_FileHead为文件头的起始地址; _dwRVA为给定的RVA地址;---------------------_RVAToOffset proc _lpFileHead, _dwRVA local @ret pushad mov esi, _lpFileHead assume esi:ptr IMAGE_DOS_HEADER add esi, [esi].e_lfanew ass

win32汇编实现阶乘和斐波那契数列

win32阶乘程序 .486 ;使用486处理器.model flat,stdcall include \masm32\include\msvcrt.inc includelib \masm32\lib\msvcrt.lib .data result0 dd 1;存储最终结果 inputdata dd ?;输入的阶乘的最大值 type0 db '%d',0 data4 db '请输入阶乘最大值ddddd: ',0 data1 db '请输入阶乘最大值: ',0 data2 db '阶乘结果为:

Win32汇编开始 Hello Asm

今天开始学习Win32汇编 因为自己很多都是Windows方面 所以 接触一下Win32汇编 .386 ;.386指令集 .model flat,stdcall ;工作模式 option casemap:none ;关键字大小写不敏感 include Windows.inc include kernel32.inc includelib kernel32.lib include user32.inc includelib user32.lib .data MessageBoxText db "H

【Win32汇编】编译环境配置

开始学习[Win32汇编],编译过程较为繁琐,做个记录. 使用 MASM32 提供的 ml.exe 和 link.exe,以及 VS2013 中的 nmake.exe 和资源编辑器. ml.exe: ml  [选项]  文件列表  [/link] link.exe: link  [选项]  文件列表 nmake.exe: nmake  [选项]  [描述文件名]  [宏定义]  [目标文件] /f 描述文件名:指定其他的描述文件名,而不是默认的 makefile 宏定义:指定新的定义,覆盖描述文

谈Win32汇编

最近接触到Win32汇编,才知道汇编必须是和平台相关的,如做应用则和操作系统和CPU类型相关,而做操作系统就和只和的CPU类型有关.对于<微机原理>里面的汇编,那是DOS汇编,而Win32汇编是基于Windows的汇编.DOS和Windows是两个完全不同的操作系统了. DOS汇编功能的实现依靠的是DOS系统提供的软中断,DOS程序是面向过程的单任务的:而Win32汇编功能的实现依靠的是WinAPI,基本的元素是与具体CPU类型有关的汇编指令(一般都是X86啦,因为微软就支持这个~~).然后记

【win32汇编】0x01 开篇一些乱七八糟的话

之前弄完了16位汇编,现在正式学习win32汇编,首先就是一些原理了,其实就是在16位的基础上增加了一些内容,其程序主要的结构记录如下 (1)指令集    .386     这是指定指令集 必须工作在80386的处理器上    mov cr0,eax    这类指令在特权级0上运行,编译到这个就报错    如果要写VxD等驱动程序,中间要用到特权指令.必须定义.386p    但是在正常情况只要.386就可以了,这个是运行在特权级3上面的    Pentium MMX中增加了mmx指令     

win32汇编实现一个简单的TCP服务端程序(WinSock的简单认知应用)

Windows网络编程,相信好多人都知道,但是我们一般都是用其他语言编写,例如C,C++,JAVA,python等等,这些语言都可以,但是汇编语言比较底层,利用它,我们可以更清晰的了解到网络编程的内在部分,这是其他语言不能相比的,好了,废话不多说,这其实就是这次的目的(毕竟水平欠缺,还是先来按照罗云斌老师的WIN32汇编书上的例子加以学习,举一反三吧). 说道网络编程,现在我所接触到的程序开发,工具软件的使用,库等等都是基于Windows平台的,想要了解Windows的网络编程就必须要知道Win

Win32汇编基础1

1.关于寄存器Windows 在内部频繁使用 ESI,EDI,EBP,EBX 寄存器,而且并不去检测这些寄存器的值是否被更改,所以如果要使用这些寄存器时必须先保存它们的值,待用完后再恢复它们 eax 是WIN32 API 默认的返回值存放处.ecx 是LOOP指令自动减一的寄存器,也就是一半用来计数,比如使用rep指令时,也是比较CX的值.esp 是堆栈指针,指向栈顶.ebp 经常用来在堆栈中寻址.esi 好像常常用在指针寻址中. edi 是目的地址寄存器. 2.关于堆栈 Windows为每个程

【win32汇编】0x04 第一个窗口程序

第一个win32汇编窗口程序,主要来自 win32汇编语言程序设计,然后加上了自己查阅msdn文档的一些理解,基本过程: start入口地址 --> _WinMain主函数 --> 定义一些需要用的消息实体和类实体 --> 注册窗口类 --> 建立并显示窗口 --> 消息循环 ( _ProcMain主要用于处理程序接受的消息 ) 1 ;模式定义 2 ;>>>>>>>>>>>>>>>>