#include #include "../lsapi.h" #include "exports.h" const long magicDWord = 0x49474541; struct _rgn { HRGN rgn; char* name; char *l_cmd, *r_cmd, *m_cmd; char *l_args, *r_args, *m_args; char* args; struct _rgn* next; }; struct _node { HWND hwnd; HBITMAP bg; int X, Y, W, H; char* name; struct _rgn* rgns; BOOL T,V; }; LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void LoadSetup(); void SetWindowBitmapRgn(HWND hwnd, HBITMAP bmp); char* szAppName = "ShortcutMap"; char* szVersion = "ShortcutMap v1.0 (MrJukes)"; HINSTANCE hInstance; HWND hwndMain, hwndParent, hwndDesk; int ScreenX, ScreenY; int x, y, w, h; char* lsdir; int msgs[] = {LM_GETREVID, 0}; void BangShow(HWND caller, const char* args) { HWND hwnd = FindWindow(szAppName, args); if (hwnd) ShowWindow(hwnd, SW_SHOW); } void BangHide(HWND caller, const char* args) { HWND hwnd = FindWindow(szAppName, args); if (hwnd) ShowWindow(hwnd, SW_HIDE); } void BangToggle(HWND caller, const char* args) { HWND hwnd = FindWindow(szAppName, args); if (hwnd) { if (IsWindowVisible(hwnd)) BangHide(caller, args); else BangShow(caller, args); } } void LoadSetup() { ScreenX = GetSystemMetrics(SM_CXSCREEN); ScreenY = GetSystemMetrics(SM_CYSCREEN); AddBangCommand("!ShortcutMapShow", BangShow); AddBangCommand("!ShortcutMapHide", BangHide); AddBangCommand("!ShortcutMapToggle", BangToggle); hwndDesk = FindWindow("DesktopBackgroundClass", NULL); if (!hwndDesk) hwndDesk = GetDesktopWindow(); /* *ImageMap "Name" #TH X Y imagetouse.bmp *Region "Tooltip" [0,0:10,0:10,10:0,10:0,0] "!bang" "notepad.exe" "middle.exe -flags" *Region "Tooltip" [100,100:110,100:110,110:100,110:100,100] !boom *ImageMap ~Name */ char stepf[MAX_PATH] = ""; sprintf(stepf, "%s\\step.rc", lsdir); FILE* step = fopen(stepf, "r"); if (!step) return; char temp[256] = ""; char token1[4096], token2[4096], token3[4096], token4[4096], token5[4096], token6[4096], extra_text[4096]; char* tokens[6]; tokens[0] = token1; tokens[1] = token2; tokens[2] = token3; tokens[3] = token4; tokens[4] = token5; tokens[5] = token6; while (1) { fgets(temp, 256, step); if (feof(step)) break; if (_strnicmp(temp, "*ShortcutMap", 12)) continue; int count = LCTokenize (temp, tokens, 6, extra_text); if (count >= 5) { struct _node* n = new struct _node; n->T = FALSE; n->V = TRUE; if (count >= 6) { n->X = atoi(token4); if (n->X < 0) n->X = ScreenX + n->X; else if (!n->X && token3[0] == '-') n->X = ScreenX; n->Y = atoi(token5); if (n->Y < 0) n->Y = ScreenY + n->Y; else if (!n->Y && token4[0] == '-') n->Y = ScreenY; n->bg = LoadLSImage(token6, token6); char* f = token3; while (*f) { if (*f == 'T') n->T = TRUE; else if (*f == 'H') n->V = FALSE; f++; } } else if (count == 5) { n->X = atoi(token3); if (n->X < 0) n->X = ScreenX + n->X; else if (!n->X && token2[0] == '-') n->X = ScreenX; n->Y = atoi(token4); if (n->Y < 0) n->Y = ScreenY + n->Y; else if (!n->Y && token3[0] == '-') n->Y = ScreenY; n->bg = LoadLSImage(token5, token5); } if (n->bg) { BITMAP bmp; GetObject(n->bg, sizeof(bmp), &bmp); n->W = bmp.bmWidth; n->H = bmp.bmHeight; n->name = _strdup(token2); n->hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, szAppName, token2, WS_POPUP, n->X, n->Y, n->W, n->H, hwndDesk, NULL, hInstance, 0); if (n->hwnd) { SetWindowBitmapRgn(n->hwnd, n->bg); SetWindowLong(n->hwnd, GWL_USERDATA, magicDWord); if (n->V) ShowWindow(n->hwnd, SW_SHOWNORMAL); if (n->T) SetWindowPos(n->hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); } while (1) { fgets(temp, 256, step); if (feof(step)) break; if (!_strnicmp(temp, "~ShortcutMap", 12)) break; count = LCTokenize (temp, tokens, 6, extra_text); if (count >= 4) { struct _rgn* r = new struct _rgn; r->name = _strdup(token2); char* c = strtok(token4, " "); r->l_cmd = _strdup(c); r->l_args = _strdup(strtok(NULL, "")); if (token5) { c = strtok(token5, " "); r->r_cmd = _strdup(c); r->r_args = _strdup(strtok(NULL, "")); } if (token6) { c = strtok(token6, " "); r->m_cmd = _strdup(c); r->m_args = _strdup(strtok(NULL, "")); } r->next = NULL; //[100,100:110,100:110,110:100,110:100,100] POINT points[32]; int pcount=0; char* p = strtok(token3+1, ":"); while (p) { if (pcount > 31) { MessageBox(n->hwnd, "You can only use 32 vertices in your polygon", szAppName, MB_ICONERROR | MB_SYSTEMMODAL | MB_OK); break; } char x[10] = ""; char y[10] = ""; char* delim = strchr(p, ','); if (delim) { strncpy(x, p, delim-p); strcpy(y, delim+1); points[pcount].x = atoi(x); points[pcount].y = atoi(y); pcount++; } p = strtok(NULL, ":]"); } if (pcount) { r->rgn = CreatePolygonRgn((const POINT*)&points, pcount, WINDING); } if (n->rgns) r->next = n->rgns; n->rgns = r; } } SetProp(n->hwnd, szAppName, (HANDLE)n); } else { delete n; } } } fclose(step); } int initModuleEx(HWND parent, HINSTANCE dllInst, LPCSTR szPath) { WNDCLASS wc; lsdir = _strdup(szPath); hwndParent = parent; hInstance = dllInst; memset(&wc,0,sizeof(wc)); wc.lpfnWndProc = WndProc; // our window procedure wc.hInstance = dllInst; // hInstance of DLL wc.lpszClassName = szAppName; // our window class name if (!RegisterClass(&wc)) { MessageBox(parent, "Error: Could not register window class", szAppName, MB_OK | MB_ICONERROR); return 1; } LoadSetup(); hwndMain = CreateWindowEx(WS_EX_TOOLWINDOW, szAppName, szAppName, WS_POPUP, x, y, w, h, NULL, NULL, dllInst, NULL); if (!hwndMain) return 1; //if (GetRCBool("ShortcutMapStartHidden", FALSE)) ShowWindow(hwndMain, SW_SHOW); //if (GetRCBool("ShortcutMapAlwaysOnTop", TRUE)) SetWindowPos(hwndMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE); SetWindowLong(hwndMain, GWL_USERDATA, magicDWord); SendMessage(hwndParent, LM_REGISTERMESSAGE, (WPARAM)hwndMain, (LPARAM)msgs); return 0; } int quitModule(HINSTANCE dll) { RemoveBangCommand("!ShortcutMapShow"); RemoveBangCommand("!ShortcutMapHide"); RemoveBangCommand("!ShortcutMapToggle"); HWND hwnd; while ((hwnd = FindWindow(szAppName, "")) != NULL) { struct _node* n = (struct _node*)GetProp(hwnd, szAppName); if (n) { while (n->rgns) { struct _rgn* r = n->rgns; n->rgns = r->next; delete r; } RemoveProp(n->hwnd, szAppName); DeleteObject(n->bg); DestroyWindow(n->hwnd); } } SendMessage(hwndParent, LM_UNREGISTERMESSAGE, (WPARAM)hwndMain, (LPARAM)msgs); DestroyWindow(hwndMain); UnregisterClass(szAppName, dll); return 0; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { int BUTTON=0; switch (msg) { case WM_ERASEBKGND: return 0; case LM_GETREVID: { LPSTR buf = (LPSTR)(lParam); strcpy(buf, szVersion); return strlen(buf); } break; case WM_PAINT: { struct _node* n = (struct _node*)GetProp(hwnd, szAppName); if (n) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); HDC buf = CreateCompatibleDC(hdc); HBITMAP oldbuf = (HBITMAP)SelectObject(buf, n->bg); BitBlt(hdc, 0, 0, n->W, n->H, buf, 0, 0, SRCCOPY); SelectObject(buf, oldbuf); EndPaint(hwnd, &ps); } } break; case WM_RBUTTONUP: BUTTON=1; case WM_MBUTTONUP: if (!BUTTON) BUTTON=2; case WM_LBUTTONUP: { struct _node* n = (struct _node*)GetProp(hwnd, szAppName); int x = LOWORD(lParam); int y = HIWORD(lParam); if (n) { struct _rgn* r = n->rgns; while (r) { if (PtInRegion(r->rgn, x, y)) { char* cmd; char* args; switch (BUTTON) { case 0: { cmd = r->l_cmd; args = r->l_args; } break; case 1: { cmd = r->r_cmd; args = r->r_args; } break; case 2: { cmd = r->r_cmd; args = r->r_args; } break; } if (*cmd == '!') ParseBangCommand(n->hwnd, cmd, args); else ShellExecute(NULL, "open", cmd, args, NULL, SW_SHOWNORMAL); break; } r=r->next; } } } break; } return DefWindowProc(hwnd,msg, wParam,lParam); } void SetWindowBitmapRgn(HWND hwnd, HBITMAP bmp) { if (hwnd && bmp) { int x=0, y=0; HDC hdc = CreateCompatibleDC(NULL); HRGN hTransRgn=NULL; HRGN hMainRgn=NULL; BITMAP bitmap; GetObject(bmp, sizeof(bitmap), &bitmap); SelectObject(hdc, bmp); hMainRgn = CreateRectRgn(0, 0, bitmap.bmWidth, bitmap.bmHeight); for (y=0; y < bitmap.bmHeight; x=0, y++) { for (x=0; x < bitmap.bmWidth; x++) { COLORREF c = GetPixel(hdc, x, y); if (c == 0x00FF00FF) { HRGN hTempRgn = CreateRectRgn(x, y, x+1, y+1); if (!hTransRgn) hTransRgn = CreateRectRgn(x, y, x+1, y+1); CombineRgn(hTransRgn, hTransRgn, hTempRgn, RGN_OR); DeleteObject(hTempRgn); } } } CombineRgn(hMainRgn, hMainRgn, hTransRgn, RGN_DIFF); SetWindowRgn(hwnd, hMainRgn, FALSE); DeleteDC(hdc); DeleteObject(hTransRgn); DeleteObject(hMainRgn); } else { RECT r; HRGN rgn; GetClientRect(hwnd, &r); rgn = CreateRectRgn(r.left, r.top, r.right, r.bottom); SetWindowRgn(hwnd, rgn, FALSE); } }