小辉论坛精华贴
Q://问了无数大虾,可无一人知道??!!用VC和SDK(不用MFC)编程如何将HINST_COMMCTRL系统提供的图形按钮改成自己的位图?
//问题:如何将HINST_COMMCTRL系统提供的图形按钮改成自己的位图?问题在下面!我有注释!
#include <windows.h>
#include <commdlg.h>
#include <stdio.h>
#include <stdlib.h>
#include <commctrl.h>
#include "窗口类控件示例.h"
OPENFILENAME ofn;
HWND hStatusBar,hToolBar;
HINSTANCE hInst;
int RightEnd[2];
LPNMHDR lpnmhdr;
LPTOOLTIPTEXT lpttext;
//定义工具栏按钮
TBBUTTON tbButton[]=
{
STD_FILENEW,IDM_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0,
STD_FILEOPEN,IDM_OPEN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0,
STD_FILESAVE,IDM_SAVE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0,
0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,0,0,
STD_CUT,IDM_CUT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0,
STD_COPY,IDM_COPY,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0,
STD_PASTE,IDM_PASTE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0,
};
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInst,
LPSTR lpszCmdLine,
int nCmdShow)
{
HWND hwnd ;
MSG Msg ;
HACCEL hAccel;
WNDCLASS wndclass ;
char lpszMenuName[]="Menu";
char lpszClassName[] = "窗口类控件";
char lpszTitle[]= "窗口类控件示例";
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject( WHITE_BRUSH) ;
wndclass.lpszMenuName = lpszMenuName ;
wndclass.lpszClassName = lpszClassName ;
if( !RegisterClass( &wndclass))
{
MessageBeep(0) ;
return FALSE ;
}
hwnd = CreateWindow(lpszClassName,
lpszTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL) ;
ShowWindow( hwnd, nCmdShow) ;
UpdateWindow(hwnd);
InitCommonControls(); //初始化通用控件
hInst=hInstance;
hAccel=LoadAccelerators(hInst,lpszMenuName);
while( GetMessage(&Msg, NULL, 0, 0))
{
if (!TranslateAccelerator(hwnd,hAccel,&Msg))
{
TranslateMessage( &Msg) ;
DispatchMessage( &Msg) ;
}
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static char szFilter[] = "Text Files (*.TXT)\0*.txt\0" "All Files (*.*)\0*.*\0\0" ;
static char lpstrFileName[]="";
static RECT WinRect;
switch(message)
{
case WM_CREATE:
//初始化对话框结构
ofn.lStructSize = sizeof (OPENFILENAME) ;
ofn.hwndOwner = hwnd ;
ofn.hInstance = NULL ;
ofn.lpstrFilter = szFilter ;
ofn.lpstrCustomFilter = NULL ;
ofn.nMaxCustFilter = 0 ;
ofn.nFilterIndex = 1 ;
ofn.lpstrFile = NULL ;
ofn.nMaxFile = 0 ;
ofn.lpstrFileTitle = NULL ;
ofn.nMaxFileTitle = 0 ;
ofn.lpstrInitialDir = NULL ;
ofn.lpstrTitle = NULL ;
ofn.Flags = 0 ;
ofn.nFileOffset = 0 ;
ofn.nFileExtension = 0 ;
ofn.lpstrDefExt = NULL ;
ofn.lCustData = 0 ;
ofn.lpfnHook = NULL ;
ofn.lpTemplateName = NULL ;
//创建工具栏
//问题在此处,如何将HINST_COMMCTRL系统提供的图形按钮改成自己的位图?
hToolBar=CreateToolbarEx(hwnd,
WS_CHILD|WS_BORDER|WS_VISIBLE
|TBSTYLE_TOOLTIPS,
ID_TOOLBAR,
7,//该工具栏包含7个图形按钮
HINST_COMMCTRL,//使用系统提供的图形按钮
IDB_STD_SMALL_COLOR,
tbButton,
7,
0,0,
0,0,
sizeof(TBBUTTON));
//创建状态栏
hStatusBar=CreateStatusWindow(
WS_CHILD|WS_VISIBLE,
"",
hwnd,
ID_STATUSBAR);
//设置状态栏
//获取用户区坐标
GetClientRect(hwnd,&WinRect);
RightEnd[0]=WinRect.right*2/3;
RightEnd[1]=WinRect.right;
//设置状态栏各部分的大小
SendMessage(hStatusBar,SB_SETPARTS,(WPARAM)2,
(LPARAM)RightEnd);
//设置状态栏各部分的文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)0,
(LPARAM)"欢迎使用状态栏");
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"应用程序已准备好");
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_NEW:
//在状态栏中显示文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"新建文件");
break;
case IDM_OPEN:
//在状态栏中显示文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"打开文件");
//设置“打开”对话框
ofn.lpstrFile=lpstrFileName;
ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST
|OFN_HIDEREADONLY;
ofn.lpstrTitle="打开";
//调用函数GetOpenFileName显示对话框
GetOpenFileName(&ofn);
//文件读写操作
break;
case IDM_SAVE:
//在状态栏中显示文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"保存文件");
//存储操作
//文件保存成功则显示消息框
MessageBox(hwnd,"文件保存成功!","文件保存",MB_OK);
break;
case IDM_SAVEAS:
//在状态栏中显示文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"另存文件");
//设置“另存为”对话框
ofn.lpstrFile=lpstrFileName;
ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST
|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
ofn.lpstrTitle="另存为";
//调用函数GetSaveFileName显示对话框
GetSaveFileName(&ofn);
//存储操作
//文件保存成功则显示消息框
MessageBox(hwnd,"文件保存成功!","文件保存",MB_OK);
break;
case IDM_CLOSE:
//在状态栏中显示文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"关闭文件");
break;
case IDM_EXIT:
SendMessage(hwnd,WM_DESTROY,0,0);
break;
case IDM_CUT:
//在状态栏中显示文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"剪切");
break;
case IDM_COPY:
//在状态栏中显示文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"复制");
break;
case IDM_PASTE:
//在状态栏中显示文本
SendMessage(hStatusBar,SB_SETTEXT,(WPARAM)1,
(LPARAM)"粘贴");
break;
case IDM_DELETE:
break;
case IDM_ABOUT:
MessageBox(hwnd,"通用控件综合示例","关于",MB_OK);
break;
}
break;
case WM_NOTIFY:
//设置工具栏提示的文本
lpnmhdr=(LPNMHDR)lParam;
if (lpnmhdr->code==TTN_NEEDTEXT)
{
lpttext=(LPTOOLTIPTEXT)lParam;
switch(lpttext->hdr.idFrom)
{
case IDM_NEW:
lpttext->lpszText="新建";
break;
case IDM_OPEN:
lpttext->lpszText="打开";
break;
case IDM_SAVE:
lpttext->lpszText="保存";
break;
case IDM_CUT:
lpttext->lpszText="剪切";
break;
case IDM_COPY:
lpttext->lpszText="复制";
break;
case IDM_PASTE:
lpttext->lpszText="粘贴";
break;
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
//附:
//窗口类控件示例.h
#define IDM_NEW 10
#define IDM_OPEN 11
#define IDM_CLOSE 12
#define IDM_SAVE 13
#define IDM_SAVEAS 14
#define IDM_EXIT 15
#define IDM_CUT 16
#define IDM_COPY 17
#define IDM_PASTE 18
#define IDM_DELETE 19
#define IDM_ABOUT 20
#define IDE_EDIT 21
#define ID_TOOLBAR 22
#define ID_STATUSBAR 23
//附:
//窗口类控件示例.rc
#include <windows.h>
#include "窗口类控件示例.h"
Menu MENU DISCARDABLE
{
POPUP "文件(&F)"
{
MENUITEM "新建(&N)\t Ctrl+N", IDM_NEW
MENUITEM "打开(&O)\t Ctrl+O", IDM_OPEN
MENUITEM "关闭(&C)", IDM_CLOSE
MENUITEM SEPARATOR
MENUITEM "保存(&S)\t Ctrl+S", IDM_SAVE
MENUITEM "另存为(&A)", IDM_SAVEAS
MENUITEM SEPARATOR
MENUITEM "退出(&X)", IDM_EXIT
}
POPUP "编辑(&E)"
{
MENUITEM "剪切(&T)\t Ctrl+X", IDM_CUT
MENUITEM "复制(&C)\t Ctrl+C", IDM_COPY
MENUITEM "粘贴(&P)\t Ctrl+V", IDM_PASTE
MENUITEM "删除(&D)\t Del", IDM_DELETE
}
POPUP "帮助(&H)"
{
MENUITEM "关于(&A)...", IDM_ABOUT
}
}
Menu ACCELERATORS
{
"^N", IDM_NEW
"^O", IDM_OPEN
"^S", IDM_SAVE
"^X", IDM_CUT
"^C", IDM_COPY
"^V", IDM_PASTE
VK_DELETE, IDM_DELETE, VIRTKEY
}
cipher ___Answer
增加位图资源:
IDB_TOOLBAR BITMAP DISCARDABLE "Toolbar.bmp"
改一下创建Toolbar的方式:
hToolBar=CreateToolbarEx(hwnd,
WS_CHILD|WS_BORDER|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE
|TBSTYLE_TOOLTIPS,
ID_TOOLBAR,
7,//该工具栏包含7个图形按钮
hInst,//使用进程的实例
IDB_TOOLBAR,//位图资源的id
tbButton,
7,
0,0,
0,0,
sizeof(TBBUTTON));
按理说这样就可以了,但你的那个程序就是不行。我专门写了一个程序,的确是可以的,要不你先下载下来看一下,创建toolbar的方法和你的那个几乎一样,但用起来就很正常。 http://go.163.com/~backrush/tbtest.zip
Q:
多谢!你的程序很好!
可我用的是纯C(SDK)的方式编程,看来还是有些不同,可是MSDN中的SDK例子中有个REPIT程序也是用 C FOR SDK方式的,可惜太复杂了!到底是怎么回事情?不得而知,这个问题看来是没有答案了,你要是解决了,希望告诉我,谢谢了!
cipher ___Answer
问题找到了,出在这:
InitCommonControls(); //初始化通用控件
hInst=hInstance;
不该在CreateWindow。
其实可以不用InitCommonControls(),所以位置错了也没关系,但hInst在这儿赋值就是问题所在。
在CreateWindow的时候,系统向WndProc发送WM_CREATE消息,而这时候hInst还没有赋值。不是进程的实例,可以跟踪一下,这时的hInst 是0。把hInst=hInstance放到CreateWindow前面就可以了。
除了前面提到的两处以外,tbBottun也需要改。可以参照我的程序。
其实错误原因并不奇怪,如果足够冷静,不难发现的。
谢谢你,让我有多了一点教训——奇怪的问题可能有一个简单的答案。
Q:
C/C++的斑竹果然不同凡响呀!!!
我被这个问题困扰了许久,问了许多人,甚至打算放弃学习它了,唉,天无绝人之路呀!我在这里多谢了!!
以后或许还要麻烦你了!
向斑竹致敬!!!!