WZをタブ化するプラグインマクロ。
遊びで途中まで適当に作ってみたけど、使わないしメンテする気もないからここに置いてみる。
デバックはしてないは、機能はまともにないは、しかも実装はかなり無理矢理&適当なんで、ちゃんとした物にしたいならスレ住人でがんばってくれ。
現時点では多重化だとまともに動かないし、高速オープンだと動かしてもいない。
#pragma myVersion=100 #include <windows.h> #include <windowsx.h> #pragma multidef+ #include <commctrl.h> #pragma multidef- //#define DEBUG #ifdef DEBUG #include "stdout.txc" #define DBPRINTF printf #else #define DBPRINTF 1 ? 0 : printf #endif static int WM_TWEVENT; #define HOOKHANDLERSTART { HOOKRESULT hookReturn = HOOK_CONTINUE; #define HOOKHANDLEREND return hookReturn;} #define TXEVEXECIDM_HANDLER(code, func) {if (uMsg == WM_TXEVENT && wParam == TXEVENT_IDMEXEC && lParam == code) {if (func(text) == HOOK_CAPTURE) hookReturn = HOOK_CAPTURE;}} #define TXEVEXECEDIDM_HANDLER(code, func) {if (uMsg == WM_TXEVENT && wParam == TXEVENT_IDMEXECED && lParam == code) {if (func(text) == HOOK_CAPTURE) hookReturn = HOOK_CAPTURE;}} #define TXEVENT_HANDLER(code, func) {if (uMsg == WM_TXEVENT && wParam == code) {if (func(text) == HOOK_CAPTURE) hookReturn = HOOK_CAPTURE;}} #define MESSAGE_HANDLER(code, func) {if (uMsg == code) {if (func(text, wParam, lParam) == HOOK_CAPTURE) hookReturn = HOOK_CAPTURE;}} #define ACTIVATE_HANDLER(code, func) {if (uMsg == WM_ACTIVATE && LOWORD(wParam) == code) {if (func(text) == HOOK_CAPTURE) hookReturn = HOOK_CAPTURE;}} typedef struct tagTABWZ{ HWND hwndbase; HWND hwndTabbar; HWND hwndTab; LONG BaseWindowProcOrg; LONG TabbarWindowProcOrg; BOOL fDestry; struct tagTABWZ *prev; struct tagTABWZ *next; } TABWZ; textvar TABWZ *pTabWz; static FARPROC BaseWindowProc = NULL; static FARPROC TabbarWindowProc = NULL; void main(TX *text) { } #define TAB_HEIGHT 20 static TABWZ *GetTabWzInfo(HWND hwnd, TX *text) { TABWZ *pTabWz = text::pTabWz; while (pTabWz) { if (pTabWz->hwndbase == hwnd) { return pTabWz; } pTabWz = pTabWz->next; } return NULL; } static void freeTabWz(TABWZ *pTabWz, TX *text) { if (pTabWz->fDestry) { if (pTabWz->prev) { pTabWz->prev->next = pTabWz->next; } else { text::pTabWz = pTabWz->next; } if (pTabWz->next) { pTabWz->next->prev = pTabWz->prev; } free(pTabWz); if (pTabWz == text::pTabWz) { text::pTabWz = NULL; } } } LRESULT CALLBACK TabbarWindowCallBack(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { TX* text = hwndbaseGetText(GetParent(hwnd)); LRESULT lResult; if (uMsg == WM_NOTIFY) { if (((NMHDR *)lParam)->code == TCN_SELCHANGE) { TABWZ *pTabWz = GetTabWzInfo(text->hwndbase, text); if (pTabWz) { int iSetCurSel = TabCtrl_GetCurSel(pTabWz->hwndTab); TCITEM tc_item; tc_item.mask = TCIF_PARAM; TabCtrl_GetItem(pTabWz->hwndTab, iSetCurSel, &tc_item); RECT rc; GetWindowRect(pTabWz->hwndbase, &rc); HWND hwndbaseActive = (HWND)tc_item.lParam; WINDOWPLACEMENT wndpl; if (GetWindowPlacement(text->hwndbase, &wndpl)) { SetWindowPlacement(hwndbaseActive, &wndpl); ShowWindow(hwndbaseActive, SW_SHOW); SetForegroundWindow(hwndbaseActive); ShowWindow(pTabWz->hwndbase, SW_HIDE); } } return 0; } } else if (uMsg == WM_DESTROY) { TABWZ *pTabWz = GetTabWzInfo(text->hwndbase, text); if (pTabWz) { lResult = CallWindowProc((WNDPROC)pTabWz->TabbarWindowProcOrg, hwnd, uMsg, wParam, lParam); SetWindowLong(hwnd, GWL_WNDPROC, pTabWz->TabbarWindowProcOrg); } } else { TABWZ *pTabWz = GetTabWzInfo(text->hwndbase, text); if (pTabWz) { lResult = CallWindowProc((WNDPROC)pTabWz->TabbarWindowProcOrg, hwnd, uMsg, wParam, lParam); } } return lResult; } LRESULT CALLBACK BaseWindowCallBack(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { TX* text = hwndbaseGetText(hwnd); LRESULT lResult; if (uMsg == WM_TWEVENT) { if (wParam == 0) { return 1; } else if (wParam == 1) { ; } } else if (uMsg == WM_SIZE) { TABWZ *pTabWz = GetTabWzInfo(hwnd, text); if (pTabWz) { lResult = CallWindowProc((WNDPROC)pTabWz->BaseWindowProcOrg, hwnd, uMsg, wParam, lParam); RECT rc; GetWindowRect(text->hwndtext, &rc); POINT Pt; Pt.x = rc.left; Pt.y = rc.top; ScreenToClient(text->hwndbase, &Pt); SetWindowPos(text->hwndtext, NULL, Pt.x, Pt.y+TAB_HEIGHT, rc.right-rc.left, (rc.bottom-rc.top)-TAB_HEIGHT, SWP_NOZORDER); SetWindowPos(pTabWz->hwndTabbar, NULL, 0, 0, rc.right-rc.left, TAB_HEIGHT, SWP_NOZORDER); } } else if (uMsg == WM_DESTROY) { TABWZ *pTabWz = GetTabWzInfo(hwnd, text); if (pTabWz) { pTabWz->fDestry = TRUE; DestroyWindow(pTabWz->hwndTabbar); lResult = CallWindowProc((WNDPROC)pTabWz->BaseWindowProcOrg, hwnd, uMsg, wParam, lParam); SetWindowLong(hwnd, GWL_WNDPROC, pTabWz->BaseWindowProcOrg); freeTabWz(pTabWz, text); } } else { TABWZ *pTabWz = GetTabWzInfo(hwnd, text); if (pTabWz) { lResult = CallWindowProc((WNDPROC)pTabWz->BaseWindowProcOrg, hwnd, uMsg, wParam, lParam); } } return lResult; } typedef struct { HWND hwnd; mchar szTabTitle[CCHPATHNAME]; } FILELISTITEM; BOOL GetWzWindowTabData(FILELISTITEM *item) { BOOL fReslut = FALSE; TX *text = hwndbaseGetText(item->hwnd); DWORD dwProcessId; GetWindowThreadProcessId(item->hwnd, &dwProcessId); HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, dwProcessId); if (hProcess) { DWORD dwRead; struct tagMBEDIT* mbedit; if (ReadProcessMemory(hProcess, &text->mbedit, &mbedit, sizeof(struct tagMBEDIT*), &dwRead)) { if (!mbedit) { mchar szTitle[CCHPATHNAME]; int iWindowTitleLength = GetWindowTextLength(item->hwnd); mchar *pszTitle = malloc(iWindowTitleLength + 1); if (pszTitle) { GetWindowText(item->hwnd, pszTitle, iWindowTitleLength + 1); mchar *p1 = NULL, *p2 = pszTitle; while ((p1 = strstr(p2+1, " - "))) { p2 = p1; } if (p2 != pszTitle) { p1 = p2; while (p1 != pszTitle && *(p1-1) != '\\') p1--; *p2 = '\0'; strcpy(item->szTabTitle, p1); fReslut = TRUE; } free(pszTitle); } } } CloseHandle(hProcess); } return fReslut; } BOOL InitTabItems(HWND hwndTab, HWND hwndbase) { int iInsert = 0, iSelect = 0; for (int i = 0; i < sh->nOpen; i++) { FILELISTITEM item; item.hwnd = sh->tWzprocess[i].hwnd; if (item.hwnd == hwndbase || SendMessage(item.hwnd, WM_TWEVENT, 0, 0)) { if (GetWzWindowTabData(&item)) { TCITEM tc_item; tc_item.mask = TCIF_TEXT | TCIF_PARAM; tc_item.pszText = item.szTabTitle; tc_item.lParam = (LPARAM)item.hwnd; TabCtrl_InsertItem(hwndTab , iInsert, &tc_item); if (sh->tWzprocess[i].hwnd == hwndbase) { iSelect = iInsert; } else { ShowWindow(sh->tWzprocess[i].hwnd, SW_HIDE); } iInsert++; } } } TabCtrl_SetCurSel(hwndTab, iSelect); return TRUE; } BOOL MakeTab(TX *text) { TABWZ *pNewTabWz = zmalloc(sizeof(TABWZ)); if (!pNewTabWz) { return FALSE; } pNewTabWz->hwndbase = text->hwndbase; RECT rc; GetWindowRect(text->hwndtext, &rc); POINT Pt; Pt.x = rc.left; Pt.y = rc.top; ScreenToClient(text->hwndbase, &Pt); SetWindowPos(text->hwndtext, NULL, Pt.x, Pt.y+TAB_HEIGHT, rc.right-rc.left, (rc.bottom-rc.top)-TAB_HEIGHT, SWP_NOZORDER); pNewTabWz->hwndTabbar = CreateWindow("#32770", "", WS_CHILD | WS_VISIBLE, Pt.x, Pt.y, rc.right-rc.left, TAB_HEIGHT, text->hwndbase, NULL, text->hInstance, NULL); SetWindowPos(pNewTabWz->hwndTabbar, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); pNewTabWz->hwndTab = CreateWindowEx(0, WC_TABCONTROL, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | TCS_FOCUSNEVER | TCS_FORCELABELLEFT , 0, 0, rc.right-rc.left, 20, pNewTabWz->hwndTabbar, NULL, text->hInstance, NULL ); SendMessage(pNewTabWz->hwndTab, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), FALSE); InitTabItems(pNewTabWz->hwndTab, text->hwndbase); pNewTabWz->next = text::pTabWz; text::pTabWz = pNewTabWz; if (!BaseWindowProc) { BaseWindowProc = txpcodeRegisterCallback(BaseWindowCallBack, 4); } if (!TabbarWindowProc) { TabbarWindowProc = txpcodeRegisterCallback(TabbarWindowCallBack, 4); } pNewTabWz->BaseWindowProcOrg = SetWindowLong(text->hwndbase, GWL_WNDPROC, (LONG)BaseWindowProc); pNewTabWz->TabbarWindowProcOrg = SetWindowLong(pNewTabWz->hwndTabbar, GWL_WNDPROC, (LONG)TabbarWindowProc); return TRUE; } BOOL UpdateTab(TX *text) { TABWZ *pTabWz = GetTabWzInfo(text->hwndbase, text); if (pTabWz) { TabCtrl_DeleteAllItems(pTabWz->hwndTab); InitTabItems(pTabWz->hwndTab, pTabWz->hwndbase); } return TRUE; } BOOL CheckTabWz(TX *text) { TABWZ *pTabWz = GetTabWzInfo(text->hwndbase, text); if (pTabWz) { return TRUE; } else { return FALSE; } } HOOKRESULT HookTxEventOpened(TX *text) { if (text->mbedit || stristr(text->szfilename, "stdout")) { return HOOK_CONTINUE; } if (CheckTabWz(text)) { UpdateTab(text); } else { MakeTab(text); } return HOOK_CONTINUE; } HOOKRESULT HookTxEventClose(TX *text) { TABWZ *pTabWz = GetTabWzInfo(text->hwndbase, text); if (pTabWz) { pTabWz->fDestry = TRUE; SetWindowLong(text->hwndbase, GWL_WNDPROC, pTabWz->BaseWindowProcOrg); DestroyWindow(pTabWz->hwndTabbar); freeTabWz(pTabWz, text); HWND hwndNextActive = NULL; BOOL bGetCurBase = FALSE; for (int i = 0; i < sh->nOpen; i++) { if (SendMessage(sh->tWzprocess[i].hwnd, WM_TWEVENT, 0, 0)) { if (sh->tWzprocess[i].hwnd == text->hwndbase) { bGetCurBase = TRUE; if (hwndNextActive) { break; } } else { hwndNextActive = sh->tWzprocess[i].hwnd; if (bGetCurBase) { break; } } } } if (hwndNextActive) { WINDOWPLACEMENT wndpl; if (GetWindowPlacement(text->hwndbase, &wndpl)) { SetWindowPlacement(hwndNextActive, &wndpl); ShowWindow(hwndNextActive, SW_SHOW); SetForegroundWindow(hwndNextActive); } } } return HOOK_CONTINUE; } HOOKRESULT HookActive(TX *text) { UpdateTab(text); return HOOK_CONTINUE; } HOOKRESULT HookTextSize(TX *text, WPARAM wParam, LPARAM lParam) { return HOOK_CONTINUE; } HOOKRESULT HookBaseSize(TX *text, WPARAM wParam, LPARAM lParam) { return HOOK_CONTINUE; } HOOKRESULT CALLBACK textHook(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { TX* text = hwndtextGetText(hwnd); HOOKHANDLERSTART MESSAGE_HANDLER(WM_SIZE, HookTextSize); TXEVENT_HANDLER(TXEVENT_CLOSE, HookTxEventClose); TXEVENT_HANDLER(TXEVENT_OPENED, HookTxEventOpened); HOOKHANDLEREND return HOOK_CONTINUE; } HOOKRESULT CALLBACK baseHook(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { TX* text = hwndtextGetText(hwnd); HOOKHANDLERSTART MESSAGE_HANDLER(WM_SIZE, HookBaseSize); ACTIVATE_HANDLER(WA_ACTIVE, HookActive); ACTIVATE_HANDLER(WA_CLICKACTIVE, HookActive); HOOKHANDLEREND return HOOK_CONTINUE; } void __on_txFrameNew(TX *text) { if (!WM_TWEVENT) WM_TWEVENT = RegisterWindowMessage("TabWz.txc for wz5"); txSetHookWndproctextTxpcode(text, textHook); txSetHookWndprocbaseTxpcode(text, baseHook); }
この記事は役に立ちましたか?