📄 tooltips.c
字号:
if (hwndActive == hwnd)
return TRUE;
return IsChild (hwndActive, hwnd);
}
static INT
TOOLTIPS_CheckTool (HWND hwnd, BOOL bShowTest)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
POINT pt;
HWND hwndTool;
INT nTool;
GetCursorPos (&pt);
hwndTool = (HWND)SendMessageW (hwnd, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
if (hwndTool == 0)
return -1;
ScreenToClient (hwndTool, &pt);
nTool = TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
if (nTool == -1)
return -1;
if (!(GetWindowLongW (hwnd, GWL_STYLE) & TTS_ALWAYSTIP) && bShowTest) {
if (!TOOLTIPS_IsWindowActive (GetWindow (hwnd, GW_OWNER)))
return -1;
}
TRACE("tool %d\n", nTool);
return nTool;
}
static LRESULT
TOOLTIPS_Activate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
infoPtr->bActive = (BOOL)wParam;
if (infoPtr->bActive)
TRACE("activate!\n");
if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1))
TOOLTIPS_Hide (hwnd, infoPtr);
return 0;
}
static LRESULT
TOOLTIPS_AddToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
TTTOOL_INFO *toolPtr;
INT nResult;
if (lpToolInfo == NULL)
return FALSE;
if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
return FALSE;
TRACE("add tool (%p) %p %d%s!\n",
hwnd, lpToolInfo->hwnd, lpToolInfo->uId,
(lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
if (infoPtr->uNumTools == 0) {
infoPtr->tools = Alloc (sizeof(TTTOOL_INFO));
toolPtr = infoPtr->tools;
}
else {
TTTOOL_INFO *oldTools = infoPtr->tools;
infoPtr->tools =
Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
memcpy (infoPtr->tools, oldTools,
infoPtr->uNumTools * sizeof(TTTOOL_INFO));
Free (oldTools);
toolPtr = &infoPtr->tools[infoPtr->uNumTools];
}
infoPtr->uNumTools++;
/* copy tool data */
toolPtr->uFlags = lpToolInfo->uFlags;
toolPtr->hwnd = lpToolInfo->hwnd;
toolPtr->uId = lpToolInfo->uId;
toolPtr->rect = lpToolInfo->rect;
toolPtr->hinst = lpToolInfo->hinst;
if (IS_INTRESOURCE(lpToolInfo->lpszText)) {
TRACE("add string id %x!\n", LOWORD(lpToolInfo->lpszText));
toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
}
else if (lpToolInfo->lpszText) {
if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA) {
TRACE("add CALLBACK!\n");
toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
}
else {
INT len = MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
NULL, 0);
TRACE("add text \"%s\"!\n", lpToolInfo->lpszText);
toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, lpToolInfo->lpszText, -1,
toolPtr->lpszText, len);
}
}
if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
toolPtr->lParam = lpToolInfo->lParam;
/* install subclassing hook */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
SetWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1,
(DWORD_PTR)hwnd);
}
else {
SetWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1,
(DWORD_PTR)hwnd);
}
TRACE("subclassing installed!\n");
}
nResult = (INT) SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
(WPARAM)hwnd, (LPARAM)NF_QUERY);
if (nResult == NFR_ANSI) {
toolPtr->bNotifyUnicode = FALSE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
} else if (nResult == NFR_UNICODE) {
toolPtr->bNotifyUnicode = TRUE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
} else {
TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
}
return TRUE;
}
static LRESULT
TOOLTIPS_AddToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
TTTOOL_INFO *toolPtr;
INT nResult;
if (lpToolInfo == NULL)
return FALSE;
if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
return FALSE;
TRACE("add tool (%p) %p %d%s!\n",
hwnd, lpToolInfo->hwnd, lpToolInfo->uId,
(lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
if (infoPtr->uNumTools == 0) {
infoPtr->tools = Alloc (sizeof(TTTOOL_INFO));
toolPtr = infoPtr->tools;
}
else {
TTTOOL_INFO *oldTools = infoPtr->tools;
infoPtr->tools =
Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
memcpy (infoPtr->tools, oldTools,
infoPtr->uNumTools * sizeof(TTTOOL_INFO));
Free (oldTools);
toolPtr = &infoPtr->tools[infoPtr->uNumTools];
}
infoPtr->uNumTools++;
/* copy tool data */
toolPtr->uFlags = lpToolInfo->uFlags;
toolPtr->hwnd = lpToolInfo->hwnd;
toolPtr->uId = lpToolInfo->uId;
toolPtr->rect = lpToolInfo->rect;
toolPtr->hinst = lpToolInfo->hinst;
if (IS_INTRESOURCE(lpToolInfo->lpszText)) {
TRACE("add string id %x\n", LOWORD(lpToolInfo->lpszText));
toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
}
else if (lpToolInfo->lpszText) {
if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW) {
TRACE("add CALLBACK!\n");
toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
}
else {
INT len = lstrlenW (lpToolInfo->lpszText);
TRACE("add text %s!\n",
debugstr_w(lpToolInfo->lpszText));
toolPtr->lpszText = Alloc ((len + 1)*sizeof(WCHAR));
strcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
}
}
if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
toolPtr->lParam = lpToolInfo->lParam;
/* install subclassing hook */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
SetWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1,
(DWORD_PTR)hwnd);
}
else {
SetWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1,
(DWORD_PTR)hwnd);
}
TRACE("subclassing installed!\n");
}
nResult = (INT) SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
(WPARAM)hwnd, (LPARAM)NF_QUERY);
if (nResult == NFR_ANSI) {
toolPtr->bNotifyUnicode = FALSE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
} else if (nResult == NFR_UNICODE) {
toolPtr->bNotifyUnicode = TRUE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
} else {
TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
}
return TRUE;
}
static void
TOOLTIPS_DelToolCommon (HWND hwnd, TOOLTIPS_INFO *infoPtr, INT nTool)
{
TTTOOL_INFO *toolPtr;
TRACE("tool %d\n", nTool);
if (nTool == -1)
return;
/* make sure the tooltip has disappeared before deleting it */
TOOLTIPS_Hide(hwnd, infoPtr);
/* delete text string */
toolPtr = &infoPtr->tools[nTool];
if (toolPtr->lpszText) {
if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
!IS_INTRESOURCE(toolPtr->lpszText) )
Free (toolPtr->lpszText);
}
/* remove subclassing */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1);
}
else {
RemoveWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1);
}
}
/* delete tool from tool list */
if (infoPtr->uNumTools == 1) {
Free (infoPtr->tools);
infoPtr->tools = NULL;
}
else {
TTTOOL_INFO *oldTools = infoPtr->tools;
infoPtr->tools =
Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
if (nTool > 0)
memcpy (&infoPtr->tools[0], &oldTools[0],
nTool * sizeof(TTTOOL_INFO));
if (nTool < infoPtr->uNumTools - 1)
memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
(infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
Free (oldTools);
}
/* update any indices affected by delete */
/* destroying tool that mouse was on on last relayed mouse move */
if (infoPtr->nTool == nTool)
/* -1 means no current tool (0 means first tool) */
infoPtr->nTool = -1;
else if (infoPtr->nTool > nTool)
infoPtr->nTool--;
if (infoPtr->nTrackTool == nTool)
/* -1 means no current tool (0 means first tool) */
infoPtr->nTrackTool = -1;
else if (infoPtr->nTrackTool > nTool)
infoPtr->nTrackTool--;
if (infoPtr->nCurrentTool == nTool)
/* -1 means no current tool (0 means first tool) */
infoPtr->nCurrentTool = -1;
else if (infoPtr->nCurrentTool > nTool)
infoPtr->nCurrentTool--;
infoPtr->uNumTools--;
}
static LRESULT
TOOLTIPS_DelToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
INT nTool;
if (lpToolInfo == NULL)
return 0;
if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
return 0;
if (infoPtr->uNumTools == 0)
return 0;
nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
TOOLTIPS_DelToolCommon (hwnd, infoPtr, nTool);
return 0;
}
static LRESULT
TOOLTIPS_DelToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
INT nTool;
if (lpToolInfo == NULL)
return 0;
if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
return 0;
if (infoPtr->uNumTools == 0)
return 0;
nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
TOOLTIPS_DelToolCommon (hwnd, infoPtr, nTool);
return 0;
}
static LRESULT
TOOLTIPS_EnumToolsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
UINT uIndex = (UINT)wParam;
LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
TTTOOL_INFO *toolPtr;
if (lpToolInfo == NULL)
return FALSE;
if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
return FALSE;
if (uIndex >= infoPtr->uNumTools)
return FALSE;
TRACE("index=%u\n", uIndex);
toolPtr = &infoPtr->tools[uIndex];
/* copy tool data */
lpToolInfo->uFlags = toolPtr->uFlags;
lpToolInfo->hwnd = toolPtr->hwnd;
lpToolInfo->uId = toolPtr->uId;
lpToolInfo->rect = toolPtr->rect;
lpToolInfo->hinst = toolPtr->hinst;
/* lpToolInfo->lpszText = toolPtr->lpszText; */
lpToolInfo->lpszText = NULL; /* FIXME */
if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
lpToolInfo->lParam = toolPtr->lParam;
return TRUE;
}
static LRESULT
TOOLTIPS_EnumToolsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
UINT uIndex = (UINT)wParam;
LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
TTTOOL_INFO *toolPtr;
if (lpToolInfo == NULL)
return FALSE;
if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
return FALSE;
if (uIndex >= infoPtr->uNumTools)
return FALSE;
TRACE("index=%u\n", uIndex);
toolPtr = &infoPtr->tools[uIndex];
/* copy tool data */
lpToolInfo->uFlags = toolPtr->uFlags;
lpToolInfo->hwnd = toolPtr->hwnd;
lpToolInfo->uId = toolPtr->uId;
lpToolInfo->rect = toolPtr->rect;
lpToolInfo->hinst = toolPtr->hinst;
/* lpToolInfo->lpszText = toolPtr->lpszText; */
lpToolInfo->lpszText = NULL; /* FIXME */
if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
lpToolInfo->lParam = toolPtr->lParam;
return TRUE;
}
static LRESULT
TOOLTIPS_GetBubbleSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
INT nTool;
SIZE size;
if (lpToolInfo == NULL)
return FALSE;
if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
return FALSE;
nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
if (nTool == -1) return 0;
TRACE("tool %d\n", nTool);
TOOLTIPS_CalcTipSize (hwnd, infoPtr, &size);
TRACE("size %d x %d\n", size.cx, size.cy);
return MAKELRESULT(size.cx, size.cy);
}
static LRESULT
TOOLTIPS_GetCurrentToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
TTTOOL_INFO *toolPtr;
if (lpToolInfo == NULL)
return FALSE;
if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
return FALSE;
if (lpToolInfo) {
if (infoPtr->nCurrentTool > -1) {
toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
/* copy tool data */
lpToolInfo->uFlags = toolPtr->uFlags;
lpToolInfo->rect = toolPtr->rect;
lpToolInfo->hinst = toolPtr->hinst;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -