dポイントプレゼントキャンペーン実施中!

C言語とWIN32APIでプログラミングしています。
いつも多くの方にお世話になっています。

■ボタンの上にマウスカーソルが来た時、ボタンが反応する様な事を考えています。
■Web画面でよくあるロ-ルオーバーの様な事です。

上記の様な事を思い、下記の様に記載しました(概略)。
ところが、クリックには反応しますが
オンマウスには反応しません。

■質問
・マウスカーソルがボタンに乗った時、反応するには何が必要ですか?

case WM_DRAWITEM:
if(wp==ID_BTN_0) {
DrawText(DrawItem->hDC,str,-1,&DrawItem->rcItem,DT_CENTER);
********************************************************
//オンマウスで色を反転する.....目的
if((DrawItem->itemAction) & (ODA_FOCUS)){
InvertRect(DrawItem->hDC,(LPRECT)&DrawItem->rcItem);
}
********************************************************
if((DrawItem->itemState) & (ODS_SELECTED)){
DrawEdge(DrawItem->hDC,(LPRECT)&DrawItem->rcItem,EDGE_SUNKEN,BF_RECT);
}else{
DrawEdge(DrawItem->hDC,(LPRECT)&DrawItem->rcItem,
EDGE_RAISED,BF_RECT);
}
}
break;

A 回答 (1件)

 こんばんは。



 ホバーボタンの事かと思います。現段階で必要なものは、TrackMouseEvent()とボタンのサブクラス化です。
 中々ややこしいので、以下URLの説明を参考になさってみてください。
 http://hp.vector.co.jp/authors/VA016117/hoverbtn …
 http://hp.vector.co.jp/authors/VA016117/hoverbtn …

 一応当方からもコードを提示しておきます。3つのボタンを出して、ホバーさせます。以下参考程度に。

#include<windows.h>
#include<tchar.h>

#define ArrayCount(a) (sizeof(a)/sizeof(a[0]))

typedef struct _BUTTONDATA
{
HWND hButton;
WNDPROC wndProcOrg;
bool bHover;
} BUTTONDATA, *PBUTTONDATA;

static BUTTONDATA buttons[3] = {NULL};
const int BUTTON_COUNT = ArrayCount(buttons);
const UINT IDC_BUTTON1 = 1000;
const LPCTSTR TSTR_BUTTONDATA = TEXT("HoverButton");

LRESULT CALLBACK ButtonProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PBUTTONDATA pButton = static_cast<PBUTTONDATA>(::GetProp(hWnd, TSTR_BUTTONDATA));
switch(message)
{
case WM_MOUSEMOVE:
if(pButton->bHover == false && wParam == 0x0)
{
pButton->bHover = true;
TRACKMOUSEEVENT tme = {sizeof(tme)};
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hWnd;
::TrackMouseEvent(&tme);
::InvalidateRect(hWnd, NULL, TRUE);
}
break;

case WM_LBUTTONDOWN:
pButton->bHover = false;
break;

case WM_LBUTTONUP:
pButton->bHover = true;
break;

case WM_MOUSELEAVE:
pButton->bHover = false;
::InvalidateRect(hWnd, NULL, TRUE);
}

return ::CallWindowProc(pButton->wndProcOrg, hWnd, message, wParam, lParam);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
{
LPCREATESTRUCT pcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
PBUTTONDATA pButton = static_cast<PBUTTONDATA>(pcs->lpCreateParams);
for(int i = 0; i < BUTTON_COUNT; ++i)
{
pButton[i].hButton = ::CreateWindowEx(0, TEXT("BUTTON"), TEXT("OK"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_OWNERDRAW,
20 + (60 * i), 20, 60, 40,
hWnd, reinterpret_cast<HMENU>(IDC_BUTTON1 + i), ::GetModuleHandle(NULL), NULL);

pButton[i].wndProcOrg = reinterpret_cast<WNDPROC>(::SetWindowLong(pButton[i].hButton, GWL_WNDPROC, reinterpret_cast<LONG>(&::ButtonProc)));
::SetProp(pButton[i].hButton, TSTR_BUTTONDATA, &pButton[i]);
}
}
break;

case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT DrawItem = reinterpret_cast<LPDRAWITEMSTRUCT>(lParam);
PBUTTONDATA pButton = static_cast<PBUTTONDATA>(::GetProp(DrawItem->hwndItem, TSTR_BUTTONDATA));
if(pButton == NULL)
break;

::FillRect(DrawItem->hDC, &DrawItem->rcItem, reinterpret_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)));

TCHAR buf[256];
::GetWindowText(DrawItem->hwndItem, buf, ArrayCount(buf));
::DrawText(DrawItem->hDC, buf, ::_tcslen(buf), &DrawItem->rcItem, DT_VCENTER | DT_CENTER | DT_SINGLELINE);

if(pButton->bHover)
{
::InvertRect(DrawItem->hDC, &DrawItem->rcItem);
}
if(DrawItem->itemState & ODS_SELECTED)
{
::DrawEdge(DrawItem->hDC, &DrawItem->rcItem, EDGE_SUNKEN, BF_RECT);
}
else
{
DrawEdge(DrawItem->hDC, &DrawItem->rcItem, EDGE_RAISED, BF_RECT);
}
if(DrawItem->itemState & ODS_FOCUS)
{
::DrawFocusRect(DrawItem->hDC, &DrawItem->rcItem);
}
}
break;

case WM_CLOSE:
::DestroyWindow(hWnd);
return 0;

case WM_NCDESTROY:
::PostQuitMessage(0);
return 0;
}

return ::DefWindowProc(hWnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pszArgs, int showCmd)
{
MSG msg;

WNDCLASSEX wc = {sizeof(wc)};
wc.lpszClassName = TEXT("TEST");
wc.lpfnWndProc = &::WndProc;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.hInstance = hInst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);

if(!::RegisterClassEx(&wc))
return 0;

HWND hWnd = ::CreateWindowEx(0, wc.lpszClassName, NULL, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, &buttons[0]);

::ShowWindow(hWnd, SW_SHOW);

while(::GetMessage(&msg, NULL, 0, 0) == TRUE)
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}

return msg.wParam;
}
    • good
    • 0
この回答へのお礼

おはようございます。
早速、ご教示ありがとうございます。

勉強します。
ありがとうございます。

お礼日時:2010/01/12 08:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!