想做成鼠标指向按钮的时候
让按钮显示另外一张图片
结果更本就没有响应
跟踪发现WM_MOUSEHOVER无法获取按钮的句柄#include "stdafx.h"
#include "UNUI.h"
#define MAX_LOADSTRING 100
#define NUM 10// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);//------------------------------------------------------------------
//创建界面控件函数
HWND CreateBtn(HWND hWndParent,int x, int y, int nWidth, int nHeight);
//------------------------------------------------------------------
//<-新增的全局变量------------------------------------------------->
HBITMAP g_skin_bmp;//皮肤文件
HBITMAP g_mask_bmp;//去掉的mask
DWORD TransparentColor = RGB(255,0,255);//mask中应用去掉颜色
//TransparentColor的设置值取决于您的mask文件中那个颜色作为镂空色
int g_nBmpW = 0;//图像的宽
int g_nBmpH = 0;//图像的高
//<---------------------------------------------------------------->
static HWND fHwnd;
//<---------------------------------------------------------------->//<---------------------------------------------------------------->
static HWND btnHwd[NUM];
static int selected[NUM]  = {2,0,0,0,0,0,0,0,0,0};
//<---------------------------------------------------------------->
int APIENTRY _tWinMain(HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPTSTR    lpCmdLine,
   int       nCmdShow)
{
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable; // 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_UNUI, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance); // 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow)) 
{
return FALSE;
} hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_UNUI); // 主消息循环:
while (GetMessage(&msg, NULL, 0, 0)) 
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} return (int) msg.wParam;
}//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
//  注释: 
//
//    仅当希望在已添加到 Windows 95 的
//    “RegisterClassEx”函数之前此代码与 Win32 系统兼容时,
//    才需要此函数及其用法。调用此函数
//    十分重要,这样应用程序就可以获得关联的
//   “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX);  wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_UNUI);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
//wcex.lpszMenuName = (LPCTSTR)IDC_UNUI;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex);
}//
//   函数: InitInstance(HANDLE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释: 
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;

hInst = hInstance; // 将实例句柄存储在全局变量中 //<---------------------------------------------------------------->
BITMAP bmp;   //用于保存图像的基础信息
HRGN LineRegion;   //组合多边形的单位,我们用它来解决多多边形组合
HRGN FullRegion;   //需要镂空的多边形
BOOL Frist = FALSE;//第一次多边形创建标志,在那之前我们并不知道多边形是否已经存在
//<-开始干活------------------------------------------------------->
//<-读取图形------------------------------------------------------->
g_mask_bmp = (HBITMAP)LoadImage(0,"Main_D.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
g_skin_bmp = (HBITMAP)LoadImage(0,"Main_N.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//<-应用变量------------------------------------------------------->
GetObject(g_mask_bmp,sizeof(BITMAP),&bmp);//这里用于获得mask.bmp的基础信息
HDC hdc = CreateCompatibleDC(NULL);  
SelectObject(hdc,g_mask_bmp);  //将mask的数据放入hdc,方便取色计算
g_nBmpH = bmp.bmHeight;
g_nBmpW = bmp.bmWidth;
for (int y = 0;y < g_nBmpH;y ++)
{
for (int x = 0; x < g_nBmpW; x++)
{
if(GetPixel (hdc,x,y) != TransparentColor )
{ LineRegion = CreateRectRgn(x,y,x+1,y+1);
if(Frist == FALSE)
{
Frist = TRUE;
FullRegion = CreateRectRgn(x,y,x+1,y+1);
}
else
CombineRgn (FullRegion, FullRegion, LineRegion, RGN_OR);
DeleteObject(LineRegion); }
}
}
DeleteDC(hdc);
//--------------------------------------------------------------
hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUPWINDOW,
CW_USEDEFAULT, 0, g_nBmpW, g_nBmpH, NULL, NULL, hInstance, NULL);
/////////////////////
fHwnd = hWnd;
/////////////////////
if (!hWnd)
{
return FALSE;
} //<---------------------------------------------------------------->
SetWindowRgn (hWnd, FullRegion, TRUE);//设置新的多边形区域为窗口区域
//<----------------------------------------------------------------> ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd); return TRUE;
}

解决方案 »

  1.   

    程序太长了
    分两次帖出来
    //
    //  函数: WndProc(HWND, unsigned, WORD, LONG)
    //
    //  目的: 处理主窗口的消息。
    //
    //  WM_COMMAND - 处理应用程序菜单
    //  WM_PAINT - 绘制主窗口
    //  WM_DESTROY - 发送退出消息并返回
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    //static HWND btnHwd[NUM];
    //static int selected[NUM]; //<-------------------------------------------------------------------->
    //导航栏位图
    HBITMAP b0bmp = (HBITMAP)LoadImage(0,"Nav_NNN.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //其它
    HBITMAP b1bmp = (HBITMAP)LoadImage(0,"Nav_H.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //鼠标悬浮
    HBITMAP b2bmp = (HBITMAP)LoadImage(0,"Nav_CS.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //选中
    //<--------------------------------------------------------------------> //<-------------------------------------------------------------------->
    //导航栏字体
    LOGFONT lf;
    HFONT h_font;
    memset(&lf,0,sizeof(lf));
    lf.lfHeight = 14;
    lf.lfCharSet = DEFAULT_CHARSET;
    strcpy(lf.lfFaceName,"仿宋_GB2312");
    h_font = CreateFontIndirect(&lf);
    //<-------------------------------------------------------------------->
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    BITMAP bmp; switch (message) 
    {
    //<---------------------------------------------------------------->
    case WM_LBUTTONDOWN:
    SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION, wParam);
    break;
    //<---------------------------------------------------------------->
    case WM_COMMAND:
    wmId    = LOWORD(wParam); 
    wmEvent = HIWORD(wParam); 
    // 分析菜单选择:
    switch (wmId)
    {
    case IDM_ABOUT:
    DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
    break;
    case IDM_EXIT:
    DestroyWindow(hWnd);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;
    case WM_PAINT:
    {
    hdc = BeginPaint(hWnd, &ps);
    // TODO: 在此添加任意绘图代码...
    //<-绘制皮肤------------------------------------------------------->
    HDC hSrcDC = CreateCompatibleDC(NULL);
    SelectObject(hSrcDC,g_skin_bmp);
    BitBlt(hdc, 0, 0, g_nBmpW, g_nBmpH, hSrcDC, 0, 0, SRCCOPY);
    DeleteDC(hSrcDC);
    //<---------------------------------------------------------------->
    EndPaint(hWnd, &ps);
    }
    ////////////////////////////////////////////////////////////////////
    break;
    case WM_CREATE:
    btnHwd[0] = CreateBtn(hWnd, 6, 24, 64, 36);
    btnHwd[1] = CreateBtn(hWnd, 94, 24, 64, 36);
    btnHwd[2] = CreateBtn(hWnd, 159, 24, 64, 36);
    break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    case WM_DRAWITEM:
    {
    LPDRAWITEMSTRUCT drawStruct = (LPDRAWITEMSTRUCT)lParam;
    if (drawStruct->hwndItem == btnHwd[0])
    {
    ///////////////////////////////////////
    //HBITMAP b0bmp = (HBITMAP)LoadImage(0,"Nav_CS.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    HBITMAP backbmp;
    if (selected[0] == 0)
    {
    backbmp = b0bmp;

    else if (selected[0] == 1)
    {
    backbmp = b1bmp;

    else if (selected[0] == 2)
    {
    backbmp = b2bmp;
    }
    HDC srcHDC =  CreateCompatibleDC(NULL);
    //SelectObject(srcHDC,b0bmp);
    SelectObject(srcHDC,backbmp);
    GetObject(backbmp,sizeof(BITMAP),&bmp);
    BitBlt(drawStruct->hDC, 0, 0, bmp.bmWidth, bmp.bmHeight, srcHDC, 0, 0, SRCCOPY);
    //<--------------------------------------------->
    SetBkMode(drawStruct->hDC, TRANSPARENT);
    //<--------------------------------------------->
    SelectObject(drawStruct->hDC, h_font);
    //<--------------------------------------------->
    if (selected[0] == 2)
    {
    SetTextColor (drawStruct->hDC, RGB(0xFF, 0xFF, 0xFF));
    }
    else
    {
    SetTextColor (drawStruct->hDC, RGB(0x00, 0x00, 0xAF));
    }
    TextOut(drawStruct->hDC, 4, 12, "影视点播", 8);
    DeleteDC(srcHDC);
    //////////////////////////////////////////////
    }
    else if (drawStruct->hwndItem == btnHwd[1])
    {
    //HBITMAP b1bmp = (HBITMAP)LoadImage(0,"Nav_H.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    HBITMAP backbmp;
    if (selected[1] == 0)
    {
    backbmp = b0bmp;

    else if (selected[1] == 1)
    {
    backbmp = b1bmp;

    else if (selected[1] == 2)
    {
    backbmp = b2bmp;
    }
    HDC srcHDC =  CreateCompatibleDC(NULL);
    SelectObject(srcHDC,backbmp);
    GetObject(backbmp,sizeof(BITMAP),&bmp);
    BitBlt(drawStruct->hDC, 0, 0, bmp.bmWidth, bmp.bmHeight, srcHDC, 0, 0, SRCCOPY);
    //<--------------------------------------------->
    SetBkMode(drawStruct->hDC, TRANSPARENT);
    //<--------------------------------------------->
    SelectObject(drawStruct->hDC, h_font);
    //<--------------------------------------------->
    //SetTextColor (drawStruct->hDC, RGB(0x00, 0x00, 0xAF));
    if (selected[1] == 2)
    {
    SetTextColor (drawStruct->hDC, RGB(0xFF, 0xFF, 0xFF));
    }
    else
    {
    SetTextColor (drawStruct->hDC, RGB(0x00, 0x00, 0xAF));
    }
    TextOut(drawStruct->hDC, 4, 12, "直播节目", 8);
    DeleteDC(srcHDC);
    }
    else if (drawStruct->hwndItem == btnHwd[2])
    {
    //HBITMAP b2bmp = (HBITMAP)LoadImage(0,"Nav_NNN.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    HDC srcHDC =  CreateCompatibleDC(NULL);
    SelectObject(srcHDC,b0bmp);
    GetObject(b2bmp,sizeof(BITMAP),&bmp);
    BitBlt(drawStruct->hDC, 0, 0, bmp.bmWidth, bmp.bmHeight, srcHDC, 0, 0, SRCCOPY);
    //<--------------------------------------------->
    SetBkMode(drawStruct->hDC, TRANSPARENT);
    //<--------------------------------------------->
    SelectObject(drawStruct->hDC, h_font);
    //<--------------------------------------------->
    SetTextColor (drawStruct->hDC, RGB(0x00, 0x00, 0xAF));
    TextOut(drawStruct->hDC, 4, 12, "测试节目", 8);
    DeleteDC(srcHDC);
    }
    }
    break;
    case WM_MOUSEMOVE:
    {
    //<---------------------------------------------------------------->
    //追踪鼠标事件
    ///*
    TRACKMOUSEEVENT eventTrack;
    eventTrack.cbSize = sizeof(eventTrack);
    eventTrack.dwFlags = TME_HOVER | TME_LEAVE;
    eventTrack.dwHoverTime = 200; //20ms
    eventTrack.hwndTrack = hWnd;
    if (TrackMouseEvent(&eventTrack))
    {
    return FALSE;
    }
    }
    break;
    case WM_MOUSEHOVER:
    {
    POINTS curPoint = MAKEPOINTS(lParam);
    POINT  cPoint;
    cPoint.x = curPoint.x;
    cPoint.y = curPoint.y;
    //cPoint.x = 120;
    //cPoint.y = 40;

    ScreenToClient(fHwnd, &cPoint);
    HWND currHwnd = WindowFromPoint(cPoint); for (int i =0; i < 10; i++)
    {
    //if (currHwnd == btnHwd[i])
    //if (hWnd == btnHwd[i])
    if (currHwnd == btnHwd[i])
    {
    if (selected[i] == 0)
    {
    selected[i] = 1;
    RECT bRect;
    GetWindowRect(hWnd, &bRect);
    InvalidateRect(btnHwd[i], &bRect, TRUE);////////////////////////////////////////////
    }
    }
    }
    return 0;
    }
    break;
    case WM_MOUSELEAVE:
    {
    for (int i =0; i < 10; i++)
    {
    //if (currHwnd == btnHwd[i])
    if (hWnd == btnHwd[i])
    {
    if (selected[i] == 1)
    {
    selected[i] = 0;
    RECT bRect;
    GetWindowRect(hWnd, &bRect);
    InvalidateRect(btnHwd[i], &bRect, TRUE);///////////////////////////////////////////////////
    }
    }
    }
    return 0;
    }
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }
      

  2.   

    分两次也不行
    看样子得分三次了// “关于”框的消息处理程序。
    LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    switch (message)
    {
    case WM_INITDIALOG:
    return TRUE; case WM_COMMAND:
    if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
    {
    EndDialog(hDlg, LOWORD(wParam));
    return TRUE;
    }
    break;
    }
    return FALSE;
    }//int CreateBtn(HWND hWndParent)
    HWND CreateBtn(HWND hWndParent,int x, int y, int nWidth, int nHeight)
    {
    HWND hwnd = 
    CreateWindow(TEXT("button"), 
    "媒体",
    WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
    x,
    y,
    nWidth,
    nHeight,
    hWndParent,
    NULL,
    NULL,
    NULL);
    return hwnd;
    }
      

  3.   

    上面是我的完整的程序
    已经弄了好长时间了
    用的是Platform SDK
    由于对Windows API不熟悉
    根本找不出来问题出在什么地方
    现在贴出来
    让各位高人指点一二
      

  4.   

    把源码发来看看  [email protected]我怎么编译也通不过
      

  5.   

    我没看得完你的代码,但这种问题你应该让窗口子类化,然后响应WM_MOUSEMOVE消息就知道是鼠标在光标是悬浮在哪个按钮里了,这样就很容易改变按钮的外观(比如你说的换过张图片等)。
      

  6.   

    hurryboylqs(中山三郎)
    我没看得完你的代码,但这种问题你应该让窗口子类化,然后响应WM_MOUSEMOVE消息就知道是鼠标在光标是悬浮在哪个按钮里了,这样就很容易改变按钮的外观(比如你说的换过张图片等)。
    ------------------------------------------------------------
    谢谢了啊
    我也是刚刚开始学SDK编程
    SDK文档太大了,都不知道从哪儿开始
    都是自己看到哪儿,写道哪儿

    还好网上的热心人比较多……
      

  7.   

    在鼠标指向按钮的时候,让按钮显示另外的一张位图??
    那就是处理消息:WM_MOUSEMOVE
    然后直接通过LoadImage实现换图~~~
      

  8.   

    if ( ! g_bMouseTracking )
        {
            TRACKMOUSEEVENT eventTrack;
            eventTrack.cbSize = sizeof(eventTrack);
            eventTrack.dwFlags =TME_HOVER | TME_LEAVE;
            eventTrack.dwHoverTime = HOVER_DEFAULT;//20ms
            eventTrack.hwndTrack = hWnd;
            if ( TrackMouseEvent(&eventTrack) )
                 return FALSE;
        }//case WM_MOUSEHOVER, WM_MOUSELEAVE
    if ( g_bMouseTracking )
        {
            g_bMouseTracking = FALSE;
            //...
        }
      

  9.   

    if ( TrackMouseEvent(&eventTrack) )
                 return FALSE;
    改为
    g_bMouseTracking = TrackMouseEvent(&eventTrack);
      

  10.   

    onestation(新手) if ( ! g_bMouseTracking )
        {
            TRACKMOUSEEVENT eventTrack;
            eventTrack.cbSize = sizeof(eventTrack);
            eventTrack.dwFlags =TME_HOVER | TME_LEAVE;
            eventTrack.dwHoverTime = HOVER_DEFAULT;//20ms
            eventTrack.hwndTrack = hWnd;
            if ( TrackMouseEvent(&eventTrack) )
                 return FALSE;
        }//case WM_MOUSEHOVER, WM_MOUSELEAVE
    if ( g_bMouseTracking )
        {
            g_bMouseTracking = FALSE;
            //...
        }-------------------------------------------------------------
    问题不在那儿
    主要是我没有子类化一个类了