home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2001 June
/
VPR0106A.BIN
/
OLS
/
TCL228
/
TCL228.lzh
/
DLLSRC.lzh
/
startmenu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-18
|
11KB
|
410 lines
/*-------------------------------------------
startmenu.c
customize start menu
Kazubon 1997-1999
---------------------------------------------*/
#include "tcdll.h"
static void OnDrawItem(HWND hwnd, DRAWITEMSTRUCT* pdis);
static BOOL IsStartMenu(HMENU hmenu);
void DeleteStartMenuRes(void);
/*------------------------------------------------
Globals
--------------------------------------------------*/
BOOL bStartMenu = FALSE;
HWND hwndBar = NULL; // タスクバーのウィンドウハンドル
WNDPROC oldWndProcBar = NULL; // ウィンドウプロシージャを保存
HDC hdcMemMenu = NULL; // メニュー描画用メモリDC
HBITMAP hbmpMenu = NULL; // メニュー描画用ビットマップ
HDC hdcMemMenuLeft = NULL; // 「Windows95」部分用メモリDC
HBITMAP hbmpMenuLeft = NULL; // 「Windows95」部分用ビットマップ
int hStartMenu = 0; // メニューの高さを保存
COLORREF colMenuLeft; // 色
static BOOL bTile = FALSE; // 並べる
/*------------------------------------------------
タスクバーのサブクラスプロシージャ
--------------------------------------------------*/
LRESULT CALLBACK WndProcBar(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
// メニューのオーナードロー
case WM_DRAWITEM:
{
DRAWITEMSTRUCT* pdis;
if(!bStartMenu) break;
pdis = (DRAWITEMSTRUCT*)lParam;
// スタートメニューでなかったらそのまま
if(wParam || !IsStartMenu((HMENU)pdis->hwndItem)) break;
OnDrawItem(hwnd, pdis);
return 1;
}
// システム色変更
case WM_SYSCOLORCHANGE:
if(hdcMemMenu) DeleteDC(hdcMemMenu); hdcMemMenu = NULL;
if(hbmpMenu) DeleteObject(hbmpMenu); hbmpMenu = NULL;
break;
// v1.7 タスクバーの表示が乱れるのを防ぐ
case WM_EXITSIZEMOVE:
PostMessage(hwnd, WM_SIZE, SIZE_RESTORED, 0);
break;
case WM_DESTROY:
DeleteStartMenuRes();
break;
}
return CallWindowProc(oldWndProcBar, hwnd, message, wParam, lParam);
}
/*------------------------------------------------
メニューのオーナードロー
--------------------------------------------------*/
void OnDrawItem(HWND hwnd, DRAWITEMSTRUCT* pdis)
{
HDC hdc;
RECT rcBox, rcItem;
HBRUSH hbr;
BITMAP bmp;
hdc = pdis->hDC;
CopyRect(&rcItem, &(pdis->rcItem));
GetClipBox(hdc, &rcBox); // メニュー全体の大きさ
// 描画用メモリDCとビットマップの作成
if(hdcMemMenu == NULL ||
(hStartMenu != rcBox.bottom && rcBox.left == 0))
{
if(hdcMemMenu) DeleteDC(hdcMemMenu);
if(hbmpMenu) DeleteObject(hbmpMenu);
hdcMemMenu = CreateCompatibleDC(hdc);
hbmpMenu = CreateCompatibleBitmap(hdc, rcBox.right, rcBox.bottom);
SelectObject(hdcMemMenu, hbmpMenu);
hbr = CreateSolidBrush(GetSysColor(COLOR_MENU));
FillRect(hdcMemMenu, &rcBox, hbr);
hStartMenu = rcBox.bottom;
}
SelectObject(hdcMemMenu, (HFONT)GetCurrentObject(hdc, OBJ_FONT));
// 背景色、文字色の設定
if(pdis->itemState & ODS_FOCUS)
{
SetTextColor(hdcMemMenu, GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkColor(hdcMemMenu, GetSysColor(COLOR_HIGHLIGHT));
}
else
{
SetTextColor(hdcMemMenu, GetSysColor(COLOR_MENUTEXT));
SetBkColor(hdcMemMenu, GetSysColor(COLOR_MENU));
}
// メモリDCにデフォルトの描画をさせる
pdis->hDC = hdcMemMenu;
CallWindowProc(oldWndProcBar, hwnd, WM_DRAWITEM, 0, (LPARAM)pdis);
// 「Windows95」の幅が、pdis->rcItem.leftに入ってくる
rcItem.right = pdis->rcItem.left;
if(rcItem.right > 0)
{
COLORREF col;
if(!bTile)
{
//「色」で塗りつぶし
col = colMenuLeft;
if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
hbr = CreateSolidBrush(col);
FillRect(hdcMemMenu, &rcItem, hbr);
DeleteObject(hbr);
}
if(hbmpMenuLeft)
GetObject(hbmpMenuLeft, sizeof(BITMAP), &bmp);
if(hbmpMenuLeft)
// && rcItem.bottom > rcBox.bottom - bmp.bmHeight)
{
int i, j;
// ビットマップ描画
for(i = 0; ; i++)
{
int y, ysrc, h, x, w;
for(j = 0; ; j++)
{
y = rcBox.bottom - ((i + 1) * bmp.bmHeight);
ysrc = 0;
h = bmp.bmHeight;
if(y < 0)
{
y = 0;
ysrc = ((i + 1) * bmp.bmHeight) - rcBox.bottom;
h -= ysrc;
}
x = j * bmp.bmWidth; w = bmp.bmWidth;
if(x + w > rcItem.right)
{
w -= ((j + 1) * bmp.bmWidth) - rcItem.right;
}
if(w > 0 && h > 0)
BitBlt(hdcMemMenu, x, y, w, h,
hdcMemMenuLeft, 0, ysrc, SRCCOPY);
if(!bTile || w < bmp.bmWidth) break;
}
if(!bTile || y == 0) break;
}
}
}
// 本当のDCにまとめて描画
BitBlt(hdc, 0, rcItem.top,
pdis->rcItem.right, rcItem.bottom - rcItem.top,
hdcMemMenu, 0, rcItem.top, SRCCOPY);
pdis->hDC = hdc;
}
/*--------------------------------------------------
スタートメニュー改造の初期化
----------------------------------------------------*/
void SetStartMenu(HWND hwndClock)
{
char fname[1024];
EndStartMenu();
// タスクバーのサブクラス化(v1.7より必ずサブクラス化)
hwndBar = GetParent(GetParent(hwndClock)); // Shell_TrayWnd
oldWndProcBar = (WNDPROC)GetWindowLong(hwndBar, GWL_WNDPROC);
SetWindowLong(hwndBar, GWL_WNDPROC, (LONG)WndProcBar);
bStartMenu = GetMyRegLong(NULL, "StartMenu", FALSE);
if(!bStartMenu) return;
colMenuLeft = GetMyRegLong(NULL, "StartMenuCol",
RGB(128, 128, 128));
bTile = GetMyRegLong(NULL, "StartMenuTile", FALSE);
GetMyRegStr(NULL, "StartMenuBmp", fname, 1024, "");
if(fname[0]) // 「Windows95」部分用のメモリDCとビットマップ作成
{
hbmpMenuLeft = ReadBitmap(hwndBar, fname, FALSE);
if(hbmpMenuLeft)
{
HDC hdc;
hdc = GetDC(hwndBar);
hdcMemMenuLeft = CreateCompatibleDC(hdc);
SelectObject(hdcMemMenuLeft, hbmpMenuLeft);
ReleaseDC(hwndBar, hdc);
}
}
}
/*--------------------------------------------------
元に戻す
----------------------------------------------------*/
void DeleteStartMenuRes(void)
{
if(hdcMemMenu) DeleteDC(hdcMemMenu); hdcMemMenu = NULL;
if(hbmpMenu) DeleteObject(hbmpMenu); hbmpMenu = NULL;
if(hdcMemMenuLeft) DeleteDC(hdcMemMenuLeft); hdcMemMenuLeft = NULL;
if(hbmpMenuLeft) DeleteObject(hbmpMenuLeft); hbmpMenuLeft = NULL;
}
void EndStartMenu(void)
{
if(hwndBar && IsWindow(hwndBar) && oldWndProcBar)
SetWindowLong(hwndBar, GWL_WNDPROC, (LONG)oldWndProcBar);
hwndBar = NULL; oldWndProcBar = NULL;
DeleteStartMenuRes();
}
/*--------------------------------------------------
スタートメニューかどうか判別
----------------------------------------------------*/
BOOL IsStartMenu(HMENU hmenu)
{
int i, count, id;
count = GetMenuItemCount(hmenu);
for(i = 0; i < count; i++)
{
id = GetMenuItemID(hmenu, i);
// 「ヘルプ」があればスタートメニュー
if(id == 503) return TRUE;
}
return FALSE;
}
// ------------------------------------------------------
// 以下、IE4用
LRESULT CALLBACK WndProcStartMenu(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
HWND hwndStartMenu = NULL; // スタートメニューのウィンドウハンドル
WNDPROC oldWndProcStartMenu = NULL;
void OnPaintStartmenuIE4(HWND hwnd, HDC hdc, BOOL bPrint);
/*--------------------------------------------------
スタートメニューウィンドウのサブクラス化
----------------------------------------------------*/
void InitStartMenuIE4(void)
{
HWND hwnd, hwndChild;
HWND hwndFound;
char classname[80];
RECT rc1, rc2;
// スタートメニューを探す
hwnd = GetDesktopWindow();
hwnd = GetWindow(hwnd, GW_CHILD);
hwndFound = NULL;
while(hwnd)
{
GetClassName(hwnd, classname, 80);
if(lstrcmpi(classname, "BaseBar") == 0)
{
if(GetWindowThreadProcessId(hwnd, NULL) ==
GetCurrentThreadId())
{
hwndChild = GetWindow(hwnd, GW_CHILD);
GetClientRect(hwnd, &rc1);
GetClientRect(hwndChild, &rc2);
if(rc1.right - rc2.right == 21 || rc2.right == 0)
{
if(hwndFound == NULL
|| (int)hwndFound > (int)hwnd)
hwndFound = hwnd;
}
}
}
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
}
hwnd = hwndFound;
if(hwnd == NULL) return;
// サブクラス化
oldWndProcStartMenu = (WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC);
SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WndProcStartMenu);
hwndStartMenu = hwnd;
}
/*--------------------------------------------------
スタートメニューウィンドウを元に戻す
----------------------------------------------------*/
void ClearStartMenuIE4(void)
{
if(hwndStartMenu && IsWindow(hwndStartMenu) && oldWndProcStartMenu)
SetWindowLong(hwndStartMenu, GWL_WNDPROC, (LONG)oldWndProcStartMenu);
hwndStartMenu = NULL; oldWndProcStartMenu = NULL;
}
/*------------------------------------------------
スタートメニューのサブクラスプロシージャ
--------------------------------------------------*/
LRESULT CALLBACK WndProcStartMenu(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
// メニューの描画
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
if(!bStartMenu) break;
hdc = BeginPaint(hwnd, &ps);
OnPaintStartmenuIE4(hwnd, hdc, FALSE);
EndPaint(hwnd, &ps);
return 0;
}
case WM_PRINT:
{
LRESULT r;
if(!bStartMenu) break;
r = CallWindowProc(oldWndProcStartMenu, hwnd, message, wParam, lParam);
OnPaintStartmenuIE4(hwnd, (HDC)wParam, TRUE);
return r;
}
// システム色変更
case WM_SYSCOLORCHANGE:
break;
}
return CallWindowProc(oldWndProcStartMenu, hwnd, message, wParam, lParam);
}
/*------------------------------------------------
スタートメニューの描画
--------------------------------------------------*/
void OnPaintStartmenuIE4(HWND hwnd, HDC hdc, BOOL bPrint)
{
RECT rc, rcWin, rcChild;
POINT pt;
COLORREF col;
HBRUSH hbr;
BITMAP bmp;
int hClient, wClient;
GetWindowRect(GetWindow(hwnd, GW_CHILD), &rcChild);
GetWindowRect(hwnd, &rcWin);
GetClientRect(hwnd, &rc);
pt.x = 0; pt.y = 0;
ClientToScreen(hwnd, &pt);
if(pt.x == rcChild.left) return;
rc.right = 21;
wClient = rc.right; hClient = rc.bottom;
if(bPrint)
{
int dx, dy;
dx = pt.x - rcWin.left; dy = pt.y - rcWin.top;
rc.left += dx; rc.right += dx;
rc.top += dy; rc.bottom += dy;
}
//「色」で塗りつぶし
col = colMenuLeft;
if(col & 0x80000000) col = GetSysColor(col & 0x00ffffff);
hbr = CreateSolidBrush(col);
FillRect(hdc, &rc, hbr);
DeleteObject(hbr);
if(hbmpMenuLeft)
{
int i, j;
GetObject(hbmpMenuLeft, sizeof(BITMAP), &bmp);
// ビットマップ描画
for(i = 0; ; i++)
{
int y, ysrc, h, x, w;
for(j = 0; ; j++)
{
y = hClient - ((i + 1) * bmp.bmHeight);
ysrc = 0;
h = bmp.bmHeight;
if(y < 0)
{
y = 0;
ysrc = ((i + 1) * bmp.bmHeight) - hClient;
h -= ysrc;
}
x = j * bmp.bmWidth; w = bmp.bmWidth;
if(x + w > wClient)
{
w -= ((j + 1) * bmp.bmWidth) - wClient;
}
if(w > 0 && h > 0)
BitBlt(hdc, rc.left + x, rc.top + y, w, h,
hdcMemMenuLeft, 0, ysrc, SRCCOPY);
if(!bTile || w < bmp.bmWidth) break;
}
if(!bTile || y == 0) break;
}
}
}