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++的斑竹果然不同凡响呀!!! 我被这个问题困扰了许久,问了许多人,甚至打算放弃学习它了,唉,天无绝人之路呀!我在这里多谢了!! 以后或许还要麻烦你了!
向斑竹致敬!!!!
|