マクロ集 / タブ化(作りかけ)


マクロ集

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);
}

この記事は役に立ちましたか?

選択肢 投票
とても役に立った 2  
役に立った 4  
どちらともいえない 0  
あまり役に立たなかった 0  
役に立たなかった 0