?? menubutton.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "MenuButton.hpp"
#include "Common.hpp"
#include <windowsx.h>
#include "PaintHelper.hpp"
#include "Debug.hpp"
#include "resource.h"
#include "Layout.hpp"
#include "Input.hpp"
//constants
const WCHAR MenuButtonImpl_t::INPUT_BUTTON[] = L"INPUT";
/*------------------------------------------------------------------------------
MenuButtonImpl_t::MenuButtonImpl_t
Ctor
------------------------------------------------------------------------------*/
MenuButtonImpl_t::MenuButtonImpl_t(
)
{
TRACE(ZONE_COMMON_CTOR);
m_IsPressedDown = false;
m_PopupIsVisible = false;
ZeroMemory(&m_Data, sizeof(m_Data));
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::~MenuButtonImpl_t
Dtor
------------------------------------------------------------------------------*/
MenuButtonImpl_t::~MenuButtonImpl_t(
)
{
TRACE(ZONE_COMMON_CTOR);
PopupMenu_t menu;
if (m_Data.IsMenu && m_Data.Value.PopupMenu)
{
menu = m_Data.Value.PopupMenu;
menu.Destroy();
}
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::GetWindowClassStyle
Specifies the windows class style to be registered
------------------------------------------------------------------------------*/
const UINT
MenuButtonImpl_t::GetWindowClassStyle(
void
)
{
// Menu button should redraw the entire window if a movement
// or size adjustment changes the width of the client area
return CS_HREDRAW;
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::ControlWindowProc
Handle messages
------------------------------------------------------------------------------*/
LRESULT
MenuButtonImpl_t::ControlWindowProc(
UINT Message,
WPARAM wParam,
LPARAM lParam,
bool& Handled
)
{
//assume we handle the message
Handled = true;
switch (Message)
{
case WM_ERASEBKGND:
//do nothing with erase background
return 1;
case WM_PAINT:
return OnPaint(reinterpret_cast<HDC>(wParam));
case WM_LBUTTONDOWN:
return OnLButtonDown(wParam, lParam);
case WM_LBUTTONUP:
return OnLButtonUp(wParam, lParam);
case WM_CAPTURECHANGED:
return OnLostCapture();
case WM_MOUSEMOVE:
return OnMouseMove(wParam, lParam);
case WM_COMMON_CALCULATE_DIMENSIONS:
return OnCalculateDimensions(reinterpret_cast<SIZE*>(lParam));
case WM_MENUBUTTON_GETDATA:
return OnGetData(reinterpret_cast<MenuButton_t::ButtonData_t*>(lParam), wParam);
case WM_MENUBUTTON_SETDATA:
return OnSetData(reinterpret_cast<const MenuButton_t::ButtonData_t*>(lParam), wParam);
case WM_MENUBUTTON_SHOW:
return OnShow(wParam);
case WM_SETTEXT:
return OnSetText(reinterpret_cast<const WCHAR*>(lParam));
default:
//we didn't handle the message
Handled = false;
return 0;
}
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::GetInputButtonText
Gets the text for the input button
------------------------------------------------------------------------------*/
int
MenuButtonImpl_t::GetInputButtonText(
__out_ecount(cchBuffer) WCHAR* pBuffer,
int cchBuffer
)
{
if (!pBuffer || (cchBuffer < 0))
{
return 0;
}
if (!m_Data.IsInputButton || !Input_IsIMEEnabled())
{
*pBuffer = 0;
return 0;
}
UINT StringId;
Input_t::IMEType_e Type = Input_GetIMEType();
switch (Type)
{
case Input_t::itMultitap:
StringId = IDS_IMEMENU_MULTITAP;
break;
case Input_t::itMultitapUppercase:
StringId = IDS_IMEMENU_MULTITAPUPPERCASE;
break;
case Input_t::itNum:
default:
StringId = IDS_IMEMENU_NUM;
break;
}
size_t cchCopied = 0;
StringCchCopyExW(
pBuffer,
cchBuffer,
CommonUtilities_t::LoadString(
GlobalData_t::s_ModuleInstance,
StringId
),
NULL,
&cchCopied,
STRSAFE_IGNORE_NULLS
);
cchCopied = cchBuffer - cchCopied;
return cchCopied;
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::OnCalculateDimensions
Calculate the size for this button
------------------------------------------------------------------------------*/
LRESULT
MenuButtonImpl_t::OnCalculateDimensions(
SIZE* pDimensions
)
{
HRESULT hr;
WCHAR TextBuffer[100] = TEXT("");
if (!pDimensions)
{
ASSERT(0);
return 0;
}
pDimensions->cy = Layout_t::ButtonHeight();
if (!(GetWindowLong(m_hwnd, GWL_STYLE) & WS_VISIBLE))
{
pDimensions->cx = 0;
return 1;
}
if (m_Data.IsInputButton)
{
UINT BitmapID = Input_IsIMEEnabled() ?
IDB_IME_BACKGROUND :
IDB_SIP_ICON;
Bitmap_t InputIcon;
hr = InputIcon.Attach(
GlobalData_t::s_GDICacheObject.LoadCachedBitmap(BitmapID)
);
ASSERT(SUCCEEDED(hr));
//Draw the sip icon centered in the button
pDimensions->cx = InputIcon.Width();
}
else
{
//get the window text and draw it
if (GetWindowText(m_hwnd, TextBuffer, _countof(TextBuffer)) > 0)
{
ASSERT(TextBuffer[0] != L'\0');
RECT CalculateRect = {0};
PaintHelper_t::CalculateTextDimensions(
TextBuffer,
-1,
&CalculateRect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX
);
pDimensions->cx = RECTWIDTH(CalculateRect);
}
if (m_Data.IsMenu)
{
Bitmap_t PopupArrow;
hr = PopupArrow.Attach(
GlobalData_t::s_GDICacheObject.LoadCachedBitmap(IDB_POPUPMENU_UP_ARROW)
);
ASSERT(SUCCEEDED(hr));
pDimensions->cx += (PopupArrow.Width() + Layout_t::PopupUpArrowRightMargin());
}
}
pDimensions->cx += 2*Layout_t::PopupTextMargin();
return 1;
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::OnGetData
Retrieve the data for this button
------------------------------------------------------------------------------*/
LRESULT
MenuButtonImpl_t::OnGetData(
MenuButton_t::ButtonData_t* pData,
UINT SizeInBytes
) const
{
if (!pData || (SizeInBytes != sizeof(MenuButton_t::ButtonData_t)))
{
ASSERT(0);
return 0;
}
memcpy(pData, &m_Data, sizeof(MenuButton_t::ButtonData_t));
return 1;
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::OnSetData
Update the data that we are tracking
------------------------------------------------------------------------------*/
LRESULT
MenuButtonImpl_t::OnSetData(
const MenuButton_t::ButtonData_t* pData,
UINT SizeInBytes
)
{
if (!pData || (SizeInBytes != sizeof(MenuButton_t::ButtonData_t)))
{
ASSERT(FALSE);
return 0;
}
PopupMenu_t menu;
//get rid of the old data...
if ( m_Data.IsMenu && m_Data.Value.PopupMenu &&
(!pData->IsMenu || (HWND)pData->Value.PopupMenu != (HWND)m_Data.Value.PopupMenu))
{
menu = m_Data.Value.PopupMenu;
menu.Destroy();
}
memcpy(&m_Data, pData, sizeof(MenuButton_t::ButtonData_t));
#ifdef DEBUG
WCHAR TextBuffer[100] = TEXT("");
GetWindowText(m_hwnd, TextBuffer, _countof(TextBuffer));
ASSERT(!m_Data.IsInputButton || (0 == wcscmp(INPUT_BUTTON, TextBuffer)));
#endif
return 1;
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::OnSetText
Handle WM_SETTEXT by forcing a redraw if the text has changed
------------------------------------------------------------------------------*/
LRESULT
MenuButtonImpl_t::OnSetText(
const WCHAR* pText
)
{
if (! pText)
{
goto exit;
}
WCHAR OldText[100] = L"";
GetWindowText(m_hwnd, OldText, _countof(OldText));
if (wcsncmp(OldText, pText, _countof(OldText)) == 0)
{
return 0;
}
//trigger repaint
InvalidateRect(m_hwnd, NULL, FALSE);
exit:
return DefWindowProc(WM_SETTEXT, 0, (LPARAM)pText);
}
/*------------------------------------------------------------------------------
MenuButtonImpl_t::OnPaint
Handle paint requests for this button
------------------------------------------------------------------------------*/
LRESULT
MenuButtonImpl_t::OnPaint(
HDC hdc
)
{
HRESULT hr;
RECT ClientRect;
WCHAR TextBuffer[100] = TEXT("");
GetClientRect(m_hwnd, &ClientRect);
PaintHelper_t paint;
//start the painting operation
hr = paint.Begin(m_hwnd);
if (FAILED(hr))
{
return 0;
}
//Parent draws the background for us
ForwardEraseBackground(paint);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -