home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2002 April
/
VPR0204A.ISO
/
OLS_XP
/
WHEELLAYERED
/
WheelLayered.lzh
/
WheelLayeredSrc.lzh
/
WheelLayered
/
WheelLayered.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-10-16
|
12KB
|
430 lines
//----------------------------------------------------------------
#include <windows.h>
#include <windowsx.h>
#include "WheelLayered.h"
#include "WheelLayeredProto.h"
#include "Resource.h"
//----------------------------------------------------------------
#define WS_EX_LAYERED 0x00080000
#define LWA_COLORKEY 0x00000001
#define LWA_ALPHA 0x00000002
#define GA_ROOT 2
//----------------------------------------------------------------
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK LinkWndProc(HWND, UINT, WPARAM, LPARAM);
HWND InitMainWindow(VOID);
HFONT SetLinkCtrl(HWND, UINT, CHAR *);
VOID ShowTrayMenu(HWND);
VOID SysTray(HWND, INT);
BOOL LoadUserLib(VOID);
VOID FreeUserLib(VOID);
VOID WindowAlpha(HWND, BOOL);
VOID CallAnimateWindow(HWND);
VOID SetDlgPos(HWND);
//----------------------------------------------------------------
HINSTANCE hInst; // インスタンス
HMODULE hmodUSER32; // user32ハンドル
BOOL bIsShowDlg; // ダイアログ表示中?
WNDPROC OldLinkProc; // リンク文字
BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD) = NULL;
BOOL (WINAPI *pGetLayeredWindowAttributes)(HWND,COLORREF *,BYTE *,DWORD *) = NULL;
HWND (WINAPI *pGetAncestor)(HWND, UINT) = NULL;
//----------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
HWND hMainWnd;
// 複数起動禁止
if(CreateMutex(NULL, TRUE, APP_NAME) == NULL) return FALSE;
if(GetLastError() == ERROR_ALREADY_EXISTS) return FALSE;
hInst = hInstance;
hMainWnd = InitMainWindow(); // メインWindow初期化
if(hMainWnd == NULL) return FALSE;
if(LoadUserLib() == FALSE){ // user32.dllロード
MessageBox(0, "WindowXPじゃないと動きません。すまんっす。", APP_NAME, MB_OK);
return FALSE;
}
if(SetHook(hMainWnd) == FALSE) return FALSE; // Hookかける
while(GetMessage(&msg, 0, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
FreeHook(); // Hook解除
FreeUserLib(); // user32.dll解放
return msg.wParam;
}
//----------------------------------------------------------
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMessage,
WPARAM wParam, LPARAM lParam)
{
POINT pt;
HWND hTargetWnd;
switch(uMessage){
case WM_CREATE:
SysTray(hWnd, NIM_ADD);
break;
case WM_APP_NOTIFYICON:
switch(lParam){
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
ShowTrayMenu(hWnd);
break;
}
break;
case WM_USER:
GetCursorPos(&pt);
hTargetWnd = WindowFromPoint(pt); // マウス位置のWindow取得
hTargetWnd = pGetAncestor(hTargetWnd, GA_ROOT); // TOPレベルWindowを取得
if(hTargetWnd != FindWindow("Progman", "Program Manager")) // Progmanはダメ
WindowAlpha(hTargetWnd, (BOOL)wParam); // 透明度変更
break;
case WM_COMMAND:
switch(LOWORD(wParam)){
case IDM_ABOUT:
bIsShowDlg = TRUE;
SetForegroundWindow(hWnd);
DialogBox(hInst, "AboutDlg", hWnd, AboutDlgProc); // About
bIsShowDlg = FALSE;
break;
case IDM_END:
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_DESTROY:
SysTray(hWnd, NIM_DELETE);
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
//------------------------------------------- MainWindow初期化
HWND InitMainWindow(VOID)
{
WNDCLASS wc;
HWND hWnd;
//メインWindowのクラス
wc.lpfnWndProc = MainWndProc;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInst, "APPICON");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = GetStockObject(NULL_BRUSH);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpszMenuName = NULL;
wc.lpszClassName = APP_NAME;
if(!RegisterClass(&wc)) return NULL;
hWnd = CreateWindowEx(
WS_EX_TOOLWINDOW,
APP_NAME, APP_NAME, WS_POPUP,
0, 0, 0, 0,
NULL, NULL, hInst, NULL);
return hWnd;
}
//------------------------------------------ About
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
static HFONT hUrlFont, hMailFont;
HDC hdc;
UINT uiID;
switch (Msg){
case WM_INITDIALOG:
SetDlgPos(hDlg);
SetDlgItemText(hDlg, IDC_URL, URL_STR);
SetDlgItemText(hDlg, IDC_MAIL, MAIL_STR);
OldLinkProc = SubclassWindow(GetDlgItem(hDlg, IDC_URL), LinkWndProc);
SubclassWindow(GetDlgItem(hDlg, IDC_MAIL), LinkWndProc);
hUrlFont = SetLinkCtrl(hDlg, IDC_URL, URL_STR);
hMailFont = SetLinkCtrl(hDlg, IDC_MAIL, MAIL_STR);
SetFocus(GetDlgItem(hDlg, IDOK));
CallAnimateWindow(hDlg);
break;
case WM_CTLCOLORSTATIC:
uiID = GetDlgCtrlID((HWND)lParam);
if(uiID == IDC_URL || uiID == IDC_MAIL){
hdc = (HDC)wParam;
SetTextColor(hdc, RGB(0,0,255));
SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
SetBkMode(hdc, TRANSPARENT);
return (BOOL)GetSysColorBrush(COLOR_3DFACE);
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDOK:
case IDCANCEL:
DeleteFont(hUrlFont);
DeleteFont(hMailFont);
EndDialog(hDlg, 0);
break;
}
}
return FALSE;
}
//--------------------------------------------------------
LRESULT CALLBACK LinkWndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
static BOOL bSelect = FALSE;
SHELLEXECUTEINFO sei;
CHAR cTxt[MAX_PATH], cExec[MAX_PATH];
LONG lRet;
DWORD dwSt, dwEd;
HCURSOR hCursor;
switch(uMsg){
case WM_SETCURSOR:
HideCaret(hWnd);
if(LOWORD(lParam) == HTCLIENT){
hCursor = LoadCursor(NULL, MAKEINTRESOURCE(32649)); // IDC_HAND
if(hCursor == NULL) hCursor = LoadCursor(hInst, "LinkCur");
SetCursor(hCursor);
}
else
SetCursor(LoadCursor(NULL, IDC_ARROW));
return 0;
case WM_LBUTTONDOWN:
SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwSt, (LPARAM)&dwEd);
if(dwSt == dwEd) bSelect = FALSE;
else bSelect = TRUE;
break;
case WM_LBUTTONUP:
lRet = CallWindowProc(OldLinkProc, hWnd, uMsg, wParam, lParam);
SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwSt, (LPARAM)&dwEd);
if((dwSt == dwEd)&&(bSelect == FALSE)){
GetWindowText(hWnd, cTxt, MAX_PATH);
lstrcpy(cExec, cTxt);
if(strstr(cTxt, "://") == NULL)
if(strstr(cTxt, "@") != NULL) wsprintf(cExec, "mailto:%s", cTxt);
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.hwnd = hWnd;
sei.lpFile = cExec;
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);
}
return lRet;
}
return CallWindowProc(OldLinkProc, hWnd, uMsg, wParam, lParam);
}
//------------------------------------------
HFONT SetLinkCtrl(HWND hDlg, UINT uiID, CHAR *pcText)
{
HDC hdc;
HWND hCtrlWnd;
LOGFONT logfont;
HFONT hLinkFont, hOldFont;
SIZE sz;
hCtrlWnd = GetDlgItem(hDlg, uiID);
hLinkFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0);
GetObject(hLinkFont, sizeof(LOGFONT), &logfont);
logfont.lfUnderline = 1;
hLinkFont = CreateFontIndirect(&logfont);
SendDlgItemMessage(hDlg, uiID, WM_SETFONT, (WPARAM)hLinkFont, 0);
hdc = CreateCompatibleDC(NULL);
hOldFont = SelectFont(hdc, hLinkFont);
GetTextExtentPoint32(hdc, pcText, lstrlen(pcText), &sz);
hOldFont = SelectFont(hdc, hOldFont);
DeleteDC(hdc);
SetWindowPos(hCtrlWnd, NULL, 0, 0, sz.cx, sz.cy,
SWP_NOZORDER|SWP_NOMOVE);
return hLinkFont;
}
//----------------------------------------------- トレイアイコンメニュー
VOID ShowTrayMenu(HWND hWnd)
{
HMENU hMenu, hMainMenu;
POINT MenuPos;
hMainMenu = LoadMenu(NULL, "MainMenu");
hMenu = GetSubMenu(hMainMenu, 0);
SetForegroundWindow(hWnd);
GetCursorPos(&MenuPos);
TrackPopupMenu(hMenu, TPM_LEFTALIGN,
MenuPos.x, MenuPos.y, 0, hWnd, NULL);
DestroyMenu(hMainMenu);
}
//---------------------------------------------------------- トレイセット
VOID SysTray(HWND hWnd, INT iMode)
{
static NOTIFYICONDATA nIcon;
switch(iMode){
case NIM_ADD: // アイコン追加
nIcon.cbSize = sizeof(NOTIFYICONDATA);
nIcon.uID = 1;
nIcon.hWnd = hWnd;
nIcon.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
nIcon.hIcon = LoadIcon(hInst, "APPICON");
nIcon.uCallbackMessage = WM_APP_NOTIFYICON;
lstrcpy(nIcon.szTip, APP_NAME);
Shell_NotifyIcon(NIM_ADD, &nIcon);
break;
case NIM_DELETE: // アイコン削除
Shell_NotifyIcon(NIM_DELETE, &nIcon);
break;
}
}
//--------------------------------------------------------
BOOL LoadUserLib(VOID)
{
hmodUSER32 = LoadLibrary("user32.dll");
if(hmodUSER32 == NULL) return FALSE;
(FARPROC)pSetLayeredWindowAttributes =
GetProcAddress(hmodUSER32, "SetLayeredWindowAttributes");
(FARPROC)pGetLayeredWindowAttributes =
GetProcAddress(hmodUSER32, "GetLayeredWindowAttributes");
(FARPROC)pGetAncestor =
GetProcAddress(hmodUSER32, "GetAncestor");
if(pSetLayeredWindowAttributes == NULL) return FALSE;
if(pGetLayeredWindowAttributes == NULL) return FALSE;
if(pGetAncestor == NULL) return FALSE;
return TRUE;
}
//--------------------------------------------------------
VOID FreeUserLib(VOID)
{
FreeLibrary(hmodUSER32);
}
//--------------------------------------------------------
VOID WindowAlpha(HWND hWnd, BOOL bPlus) // bPlus: TRUE(不透明に)/FALSE(透明に)
{
LONG lStyle;
COLORREF crKey;
BYTE btAlpha;
DWORD dwFlag;
// 現在の状態
if(pGetLayeredWindowAttributes(hWnd, &crKey, &btAlpha, &dwFlag) == FALSE){
if(bPlus == TRUE) return; // 現在不透明だから、何もしない
else{
// WS_EX_LAYEREDをセット
lStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
lStyle |= WS_EX_LAYERED;
SetWindowLong(hWnd, GWL_EXSTYLE, lStyle);
btAlpha = 255;
}
}
if(bPlus == TRUE){ // 不透明に
if(btAlpha >= 225) btAlpha = 255;
else btAlpha += 30;
}
else{ // 透明に
if(btAlpha <= 30) btAlpha = 30;
else btAlpha -= 30;
}
if(btAlpha == 255){
// WS_EX_LAYERED解除
lStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
lStyle &= ~WS_EX_LAYERED;
SetWindowLong(hWnd, GWL_EXSTYLE, lStyle);
return;
}
pSetLayeredWindowAttributes(hWnd, 0, btAlpha, LWA_ALPHA);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
//--------------------------------------------------------
VOID CallAnimateWindow(HWND hWnd)
{
typedef BOOL (CALLBACK* LPANIMATEWINDOW)(HWND , UINT, INT);
DWORD dwAnimPtn[5]
={0x00040001, 0x00040002, 0x00040004, 0x00040008, 0x00040010};
LPANIMATEWINDOW lpAnimateProc;
HANDLE hLib;
srand(GetTickCount());
hLib = LoadLibrary("user32.dll");
if(hLib == NULL) return;
lpAnimateProc = (LPANIMATEWINDOW)GetProcAddress(hLib, "AnimateWindow");
if(lpAnimateProc != NULL)
lpAnimateProc(hWnd, 200, dwAnimPtn[(UINT)(rand()%5)]);
FreeLibrary(hLib);
InvalidateRect(hWnd, NULL, FALSE);
}
//----------------------------------------------- ダイアログ位置
VOID SetDlgPos(HWND hDlg)
{
POINT pt;
INT pos = 0, x, y, sc_width, sc_heigth, sc_left, sc_top;
RECT rc;
HWND hWnd;
// ディスプレイサイズ
hWnd = FindWindow("Progman", "Program Manager");
hWnd = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL);
GetWindowRect(hWnd, &rc);
sc_width = RECT_WIDTH(rc);
sc_heigth = RECT_HEIGHT(rc);
sc_left = rc.left;
sc_top = rc.top;
// マウス位置
GetCursorPos(&pt);
x = (UINT)(sc_width/2);
y = (UINT)(sc_heigth/2);
if( pt.x > x ) pos +=1;
if( pt.y > y ) pos +=2;
// Window位置
GetWindowRect(hDlg, &rc);
// マウス位置によって、だいたい良さそうな表示位置を決定
switch(pos){
case 0:
x = (UINT)((x - RECT_WIDTH (rc))/2);
y = (UINT)((y - RECT_HEIGHT(rc))/2);
break;
case 1:
x = (UINT)((x - RECT_WIDTH (rc))/2)+x;
y = (UINT)((y - RECT_HEIGHT(rc))/2);
break;
case 2:
x = (UINT)((x - RECT_WIDTH (rc))/2);
y = (UINT)((y - RECT_HEIGHT(rc))/2)+y;
break;
case 3:
x = (UINT)((x - RECT_WIDTH (rc))/2)+x;
y = (UINT)((y - RECT_HEIGHT(rc))/2)+y;
break;
}
if(x < sc_left) x = sc_left;
if(y < sc_top) y = sc_top;
if(x + RECT_WIDTH(rc) > sc_width) x = sc_width - RECT_WIDTH(rc);
if(y + RECT_HEIGHT(rc) > sc_heigth) y = sc_heigth - RECT_HEIGHT(rc);
// ダイアログ表示
SetWindowPos(hDlg, HWND_NOTOPMOST,
x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
}