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 >
C/C++ Source or Header  |  2001-10-16  |  12KB  |  430 lines

  1. //----------------------------------------------------------------
  2. #include    <windows.h>
  3. #include    <windowsx.h>
  4. #include    "WheelLayered.h"
  5. #include    "WheelLayeredProto.h"
  6. #include    "Resource.h"
  7.  
  8. //----------------------------------------------------------------
  9. #define        WS_EX_LAYERED        0x00080000
  10. #define        LWA_COLORKEY        0x00000001
  11. #define        LWA_ALPHA            0x00000002
  12. #define        GA_ROOT                2
  13.  
  14. //----------------------------------------------------------------
  15. LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
  16. BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
  17. LRESULT CALLBACK LinkWndProc(HWND, UINT, WPARAM, LPARAM);
  18. HWND InitMainWindow(VOID);
  19. HFONT SetLinkCtrl(HWND, UINT, CHAR *);
  20. VOID ShowTrayMenu(HWND);
  21. VOID SysTray(HWND, INT);
  22. BOOL LoadUserLib(VOID);
  23. VOID FreeUserLib(VOID);
  24. VOID WindowAlpha(HWND, BOOL);
  25. VOID CallAnimateWindow(HWND);
  26. VOID SetDlgPos(HWND);
  27.  
  28. //----------------------------------------------------------------
  29. HINSTANCE    hInst;                    // インスタンス
  30. HMODULE        hmodUSER32;                // user32ハンドル
  31. BOOL        bIsShowDlg;                // ダイアログ表示中?
  32. WNDPROC        OldLinkProc;            // リンク文字
  33.  
  34. BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD) = NULL;
  35. BOOL (WINAPI *pGetLayeredWindowAttributes)(HWND,COLORREF *,BYTE *,DWORD *) = NULL;
  36. HWND (WINAPI *pGetAncestor)(HWND, UINT) = NULL;
  37.  
  38. //----------------------------------------------------------------
  39. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  40.             LPSTR lpszCmdLine, int nCmdShow)
  41. {
  42.     MSG msg;
  43.     HWND hMainWnd;
  44.  
  45.     // 複数起動禁止
  46.     if(CreateMutex(NULL, TRUE, APP_NAME) == NULL) return FALSE;
  47.     if(GetLastError() == ERROR_ALREADY_EXISTS) return FALSE;
  48.  
  49.     hInst = hInstance;
  50.     hMainWnd = InitMainWindow();        // メインWindow初期化
  51.     if(hMainWnd == NULL) return FALSE;
  52.  
  53.     if(LoadUserLib() == FALSE){            // user32.dllロード
  54.         MessageBox(0, "WindowXPじゃないと動きません。すまんっす。", APP_NAME, MB_OK);
  55.         return FALSE;
  56.     }
  57.     if(SetHook(hMainWnd) == FALSE) return FALSE;        // Hookかける
  58.     while(GetMessage(&msg, 0, 0, 0)){
  59.         TranslateMessage(&msg);
  60.         DispatchMessage(&msg);
  61.     }
  62.     FreeHook();                            // Hook解除
  63.     FreeUserLib();                        // user32.dll解放
  64.     return msg.wParam;
  65. }
  66.  
  67. //----------------------------------------------------------
  68. LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMessage,
  69.                 WPARAM wParam, LPARAM lParam)
  70. {
  71.     POINT pt;
  72.     HWND hTargetWnd;
  73.  
  74.     switch(uMessage){
  75.     case WM_CREATE:
  76.         SysTray(hWnd, NIM_ADD);
  77.         break;
  78.     case WM_APP_NOTIFYICON:
  79.         switch(lParam){
  80.         case WM_LBUTTONDOWN:
  81.         case WM_RBUTTONDOWN:
  82.             ShowTrayMenu(hWnd);
  83.             break;
  84.         }
  85.         break;
  86.     case WM_USER:
  87.         GetCursorPos(&pt);
  88.         hTargetWnd = WindowFromPoint(pt);                            // マウス位置のWindow取得
  89.         hTargetWnd = pGetAncestor(hTargetWnd, GA_ROOT);                // TOPレベルWindowを取得
  90.         if(hTargetWnd != FindWindow("Progman", "Program Manager"))    // Progmanはダメ
  91.             WindowAlpha(hTargetWnd, (BOOL)wParam);                    // 透明度変更
  92.         break;
  93.     case WM_COMMAND:
  94.         switch(LOWORD(wParam)){
  95.         case IDM_ABOUT:
  96.             bIsShowDlg = TRUE;
  97.             SetForegroundWindow(hWnd);
  98.             DialogBox(hInst, "AboutDlg", hWnd, AboutDlgProc);    // About
  99.             bIsShowDlg = FALSE;
  100.             break;
  101.         case IDM_END:
  102.             SendMessage(hWnd, WM_CLOSE, 0, 0);
  103.             break;
  104.         }
  105.         break;
  106.     case WM_DESTROY:
  107.         SysTray(hWnd, NIM_DELETE);
  108.         PostQuitMessage(0);
  109.         break;
  110.     }
  111.     return DefWindowProc(hWnd, uMessage, wParam, lParam);
  112. }
  113.  
  114. //------------------------------------------- MainWindow初期化
  115. HWND InitMainWindow(VOID)
  116. {
  117.     WNDCLASS wc;
  118.     HWND hWnd;
  119.  
  120.     //メインWindowのクラス
  121.     wc.lpfnWndProc        = MainWndProc;
  122.     wc.hInstance        = hInst;
  123.     wc.hIcon            = LoadIcon(hInst, "APPICON");
  124.     wc.hCursor            = LoadCursor(NULL, IDC_ARROW);
  125.     wc.cbClsExtra        = 0;
  126.     wc.cbWndExtra        = 0;
  127.     wc.hbrBackground    = GetStockObject(NULL_BRUSH);
  128.     wc.style            = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  129.     wc.lpszMenuName        = NULL;
  130.     wc.lpszClassName    = APP_NAME;
  131.     if(!RegisterClass(&wc)) return NULL;
  132.  
  133.     hWnd = CreateWindowEx(
  134.         WS_EX_TOOLWINDOW,
  135.         APP_NAME, APP_NAME, WS_POPUP,
  136.         0, 0, 0, 0,
  137.         NULL, NULL, hInst, NULL);
  138.     return hWnd;
  139. }
  140.  
  141. //------------------------------------------  About
  142. BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  143. {
  144.     static HFONT hUrlFont, hMailFont;
  145.     HDC hdc;
  146.     UINT uiID;
  147.  
  148.     switch (Msg){
  149.     case WM_INITDIALOG:
  150.         SetDlgPos(hDlg);
  151.         SetDlgItemText(hDlg, IDC_URL, URL_STR);
  152.         SetDlgItemText(hDlg, IDC_MAIL, MAIL_STR);
  153.         OldLinkProc = SubclassWindow(GetDlgItem(hDlg, IDC_URL), LinkWndProc);
  154.         SubclassWindow(GetDlgItem(hDlg, IDC_MAIL), LinkWndProc);
  155.         hUrlFont = SetLinkCtrl(hDlg, IDC_URL, URL_STR);
  156.         hMailFont = SetLinkCtrl(hDlg, IDC_MAIL, MAIL_STR);
  157.         SetFocus(GetDlgItem(hDlg, IDOK));
  158.         CallAnimateWindow(hDlg);
  159.         break;
  160.     case WM_CTLCOLORSTATIC:
  161.         uiID = GetDlgCtrlID((HWND)lParam);
  162.         if(uiID == IDC_URL || uiID == IDC_MAIL){
  163.             hdc = (HDC)wParam;
  164.             SetTextColor(hdc, RGB(0,0,255));
  165.             SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
  166.             SetBkMode(hdc, TRANSPARENT);
  167.             return (BOOL)GetSysColorBrush(COLOR_3DFACE);
  168.         }
  169.         break;
  170.     case WM_COMMAND:
  171.         switch (LOWORD(wParam)){
  172.         case IDOK:
  173.         case IDCANCEL:
  174.             DeleteFont(hUrlFont);
  175.             DeleteFont(hMailFont);
  176.             EndDialog(hDlg, 0);
  177.             break;
  178.         }
  179.     }
  180.     return FALSE;
  181. }
  182.  
  183. //--------------------------------------------------------
  184. LRESULT CALLBACK LinkWndProc(HWND hWnd, UINT uMsg,
  185.                 WPARAM wParam, LPARAM lParam)
  186. {
  187.     static BOOL bSelect = FALSE;
  188.     SHELLEXECUTEINFO sei;
  189.     CHAR cTxt[MAX_PATH], cExec[MAX_PATH];
  190.     LONG lRet;
  191.     DWORD dwSt, dwEd;
  192.     HCURSOR hCursor;
  193.  
  194.     switch(uMsg){
  195.     case WM_SETCURSOR:
  196.         HideCaret(hWnd);
  197.         if(LOWORD(lParam) == HTCLIENT){
  198.             hCursor = LoadCursor(NULL, MAKEINTRESOURCE(32649));        // IDC_HAND
  199.             if(hCursor == NULL) hCursor = LoadCursor(hInst, "LinkCur");
  200.             SetCursor(hCursor);
  201.         }
  202.         else
  203.             SetCursor(LoadCursor(NULL, IDC_ARROW));
  204.         return 0;
  205.     case WM_LBUTTONDOWN:
  206.         SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwSt, (LPARAM)&dwEd);
  207.         if(dwSt == dwEd) bSelect = FALSE;
  208.         else bSelect = TRUE;
  209.         break;
  210.     case WM_LBUTTONUP:
  211.         lRet =  CallWindowProc(OldLinkProc, hWnd, uMsg, wParam, lParam);
  212.         SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwSt, (LPARAM)&dwEd);
  213.         if((dwSt == dwEd)&&(bSelect == FALSE)){
  214.             GetWindowText(hWnd, cTxt, MAX_PATH);
  215.             lstrcpy(cExec, cTxt);
  216.             if(strstr(cTxt, "://") == NULL)
  217.                 if(strstr(cTxt, "@") != NULL) wsprintf(cExec, "mailto:%s", cTxt);
  218.             ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
  219.             sei.cbSize = sizeof(SHELLEXECUTEINFO);
  220.             sei.fMask = SEE_MASK_NOCLOSEPROCESS;
  221.             sei.hwnd = hWnd;
  222.             sei.lpFile = cExec;
  223.             sei.nShow = SW_SHOWNORMAL;
  224.             ShellExecuteEx(&sei);
  225.         }
  226.         return lRet;
  227.     }
  228.     return CallWindowProc(OldLinkProc, hWnd, uMsg, wParam, lParam);
  229. }
  230.  
  231. //------------------------------------------
  232. HFONT SetLinkCtrl(HWND hDlg, UINT uiID, CHAR *pcText)
  233. {
  234.     HDC hdc;
  235.     HWND hCtrlWnd;
  236.     LOGFONT logfont;
  237.     HFONT hLinkFont, hOldFont;
  238.     SIZE sz;
  239.  
  240.     hCtrlWnd = GetDlgItem(hDlg, uiID);
  241.     hLinkFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0);
  242.     GetObject(hLinkFont, sizeof(LOGFONT), &logfont);
  243.     logfont.lfUnderline = 1;
  244.     hLinkFont = CreateFontIndirect(&logfont);
  245.     SendDlgItemMessage(hDlg, uiID, WM_SETFONT, (WPARAM)hLinkFont, 0);
  246.     hdc = CreateCompatibleDC(NULL);
  247.     hOldFont = SelectFont(hdc, hLinkFont);
  248.     GetTextExtentPoint32(hdc, pcText, lstrlen(pcText), &sz);
  249.     hOldFont = SelectFont(hdc, hOldFont);
  250.     DeleteDC(hdc);
  251.     SetWindowPos(hCtrlWnd, NULL, 0, 0, sz.cx, sz.cy,
  252.         SWP_NOZORDER|SWP_NOMOVE);
  253.     return hLinkFont;
  254. }
  255.  
  256. //----------------------------------------------- トレイアイコンメニュー
  257. VOID ShowTrayMenu(HWND hWnd)
  258. {
  259.     HMENU hMenu, hMainMenu;
  260.     POINT MenuPos;
  261.  
  262.     hMainMenu = LoadMenu(NULL, "MainMenu");
  263.     hMenu = GetSubMenu(hMainMenu, 0);
  264.     SetForegroundWindow(hWnd);
  265.     GetCursorPos(&MenuPos);
  266.     TrackPopupMenu(hMenu, TPM_LEFTALIGN,
  267.         MenuPos.x, MenuPos.y, 0, hWnd, NULL);
  268.     DestroyMenu(hMainMenu);
  269. }
  270.  
  271. //---------------------------------------------------------- トレイセット
  272. VOID SysTray(HWND hWnd, INT iMode)
  273. {
  274.     static NOTIFYICONDATA nIcon;
  275.  
  276.     switch(iMode){
  277.     case NIM_ADD:                    // アイコン追加
  278.         nIcon.cbSize = sizeof(NOTIFYICONDATA);
  279.         nIcon.uID = 1;
  280.         nIcon.hWnd = hWnd;
  281.         nIcon.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
  282.         nIcon.hIcon = LoadIcon(hInst, "APPICON");
  283.         nIcon.uCallbackMessage = WM_APP_NOTIFYICON;
  284.         lstrcpy(nIcon.szTip, APP_NAME);
  285.         Shell_NotifyIcon(NIM_ADD, &nIcon);
  286.         break;
  287.     case NIM_DELETE:                // アイコン削除
  288.         Shell_NotifyIcon(NIM_DELETE, &nIcon);
  289.         break;
  290.     }
  291. }
  292.  
  293. //--------------------------------------------------------
  294. BOOL LoadUserLib(VOID)
  295. {
  296.     hmodUSER32 = LoadLibrary("user32.dll");
  297.     if(hmodUSER32 == NULL) return FALSE;
  298.     (FARPROC)pSetLayeredWindowAttributes = 
  299.         GetProcAddress(hmodUSER32, "SetLayeredWindowAttributes");
  300.     (FARPROC)pGetLayeredWindowAttributes = 
  301.         GetProcAddress(hmodUSER32, "GetLayeredWindowAttributes");
  302.     (FARPROC)pGetAncestor = 
  303.         GetProcAddress(hmodUSER32, "GetAncestor");
  304.     if(pSetLayeredWindowAttributes == NULL) return FALSE;
  305.     if(pGetLayeredWindowAttributes == NULL) return FALSE;
  306.     if(pGetAncestor == NULL) return FALSE;
  307.     return TRUE;
  308. }
  309.  
  310. //--------------------------------------------------------
  311. VOID FreeUserLib(VOID)
  312. {
  313.     FreeLibrary(hmodUSER32);
  314. }
  315.  
  316. //--------------------------------------------------------
  317. VOID WindowAlpha(HWND hWnd, BOOL bPlus)            // bPlus: TRUE(不透明に)/FALSE(透明に)
  318. {
  319.     LONG lStyle;
  320.     COLORREF crKey;
  321.     BYTE btAlpha;
  322.     DWORD dwFlag;
  323.  
  324.     // 現在の状態
  325.     if(pGetLayeredWindowAttributes(hWnd, &crKey, &btAlpha, &dwFlag) == FALSE){
  326.         if(bPlus == TRUE) return;        // 現在不透明だから、何もしない
  327.         else{
  328.             // WS_EX_LAYEREDをセット
  329.             lStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
  330.             lStyle |= WS_EX_LAYERED;
  331.             SetWindowLong(hWnd, GWL_EXSTYLE, lStyle);
  332.             btAlpha = 255;
  333.         }
  334.     }
  335.  
  336.     if(bPlus == TRUE){        // 不透明に
  337.         if(btAlpha >= 225) btAlpha = 255;
  338.         else btAlpha += 30;
  339.     }
  340.     else{                    // 透明に
  341.         if(btAlpha <= 30) btAlpha = 30;
  342.         else btAlpha -= 30;
  343.     }
  344.     if(btAlpha == 255){
  345.         // WS_EX_LAYERED解除
  346.         lStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
  347.         lStyle &= ~WS_EX_LAYERED;
  348.         SetWindowLong(hWnd, GWL_EXSTYLE, lStyle);
  349.         return;
  350.     }
  351.     pSetLayeredWindowAttributes(hWnd, 0, btAlpha, LWA_ALPHA);
  352.     InvalidateRect(hWnd, NULL, FALSE);
  353.     UpdateWindow(hWnd);
  354. }
  355.  
  356. //--------------------------------------------------------
  357. VOID CallAnimateWindow(HWND hWnd)
  358. {
  359.     typedef BOOL (CALLBACK* LPANIMATEWINDOW)(HWND , UINT, INT);
  360.     DWORD dwAnimPtn[5]
  361.             ={0x00040001, 0x00040002, 0x00040004, 0x00040008, 0x00040010};
  362.     LPANIMATEWINDOW lpAnimateProc;
  363.     HANDLE hLib;
  364.  
  365.     srand(GetTickCount());
  366.     hLib = LoadLibrary("user32.dll");
  367.     if(hLib == NULL) return;
  368.     lpAnimateProc = (LPANIMATEWINDOW)GetProcAddress(hLib, "AnimateWindow");
  369.     if(lpAnimateProc != NULL)
  370.         lpAnimateProc(hWnd, 200, dwAnimPtn[(UINT)(rand()%5)]);
  371.     FreeLibrary(hLib);
  372.     InvalidateRect(hWnd, NULL, FALSE);
  373. }
  374.  
  375. //----------------------------------------------- ダイアログ位置
  376. VOID SetDlgPos(HWND hDlg)
  377. {
  378.     POINT pt;
  379.     INT pos = 0, x, y, sc_width, sc_heigth, sc_left, sc_top;
  380.     RECT rc;
  381.     HWND hWnd;
  382.  
  383.     // ディスプレイサイズ
  384.     hWnd = FindWindow("Progman", "Program Manager");
  385.     hWnd = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL);
  386.     GetWindowRect(hWnd, &rc);
  387.     sc_width = RECT_WIDTH(rc);
  388.     sc_heigth = RECT_HEIGHT(rc);
  389.     sc_left = rc.left;
  390.     sc_top = rc.top;
  391.  
  392.     // マウス位置
  393.     GetCursorPos(&pt);
  394.     x = (UINT)(sc_width/2);
  395.     y = (UINT)(sc_heigth/2);
  396.     if( pt.x > x ) pos +=1;
  397.     if( pt.y > y ) pos +=2;
  398.  
  399.     // Window位置
  400.     GetWindowRect(hDlg, &rc);
  401.  
  402.     // マウス位置によって、だいたい良さそうな表示位置を決定
  403.     switch(pos){
  404.     case 0:
  405.         x = (UINT)((x - RECT_WIDTH (rc))/2);
  406.         y = (UINT)((y - RECT_HEIGHT(rc))/2);
  407.         break;
  408.     case 1:
  409.         x = (UINT)((x - RECT_WIDTH (rc))/2)+x;
  410.         y = (UINT)((y - RECT_HEIGHT(rc))/2);
  411.         break;
  412.     case 2:
  413.         x = (UINT)((x - RECT_WIDTH (rc))/2);
  414.         y = (UINT)((y - RECT_HEIGHT(rc))/2)+y;
  415.         break;
  416.     case 3:
  417.         x = (UINT)((x - RECT_WIDTH (rc))/2)+x;
  418.         y = (UINT)((y - RECT_HEIGHT(rc))/2)+y;
  419.         break;
  420.     }
  421.     if(x < sc_left) x = sc_left;
  422.     if(y < sc_top) y = sc_top;
  423.     if(x + RECT_WIDTH(rc) > sc_width) x = sc_width - RECT_WIDTH(rc);
  424.     if(y + RECT_HEIGHT(rc) > sc_heigth) y = sc_heigth - RECT_HEIGHT(rc);
  425.  
  426.     // ダイアログ表示
  427.     SetWindowPos(hDlg, HWND_NOTOPMOST,
  428.         x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
  429. }
  430.