004-02  前へ←  ホームへ  →次へ  004-04

No.004 - 03  自前ドッキング・ツールバー クラス化 (ドッキング・システム)


自前ドッキング・ツールバーの作成はCのままではつらいので、少しC++に移行します。

以下ドッキングツールバーを一式クラス化して、メインウィンドウの負担を軽くしています。
DOCK_SYSクラス内ドッキング・フローティング処理を一括しています。

メインウィンドウDOCK_SYSクラスをひとつ保持しておいてWM_NCACTIVATE WM_SIZE で所定の処理をするだけです。
メインウィンドウ と ビューウィンドウ のプロシージャとかはソース下の方で C のままのカタチで残してあります。


・ドッキングシステム
前回のDOCK_STRUCT構造体を元にDOCK_SYSという特殊なクラスを作っています。
メインウィンドウはDOCK_SYSクラスをひとつ保持しておいて、ドッキング関連の処理をDOCK_SYSクラスに丸投げする仕組みです。

DOCK_SYSクラスはDOCK_CONTEXTクラスをひとつ持ちドラッグ中の処理はDOCK_CONTEXTクラス内でします。





docking_test_03.cpp
#define _WIN32_IE 0x0501
#include <windows.h>
#include <commctrl.h>

TBBUTTON tool_bar_buttons[] = {
    { STD_FILENEW, 1, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
    { STD_FILEOPEN, 2, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
    { STD_FILESAVE, 3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
    { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0 },
    { STD_COPY, 4, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
    { STD_CUT, 5, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
    { STD_DELETE, 6, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
    { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0 },
    { VIEW_NEWFOLDER, 7, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
    { VIEW_PARENTFOLDER, 8, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
};

// ドック・コンテキスト・構造体
class DOCK_CONTEXT {
    public:
    HRGN m_apply_rgn, m_work_rgn, m_work_rgn2, m_last_rgn;  // リージョン
    HDC m_desk_hdc;         // デスクトップDC
    int m_now_dragging;     // ドラッグ中なら==1  そうでないなら==0
    SIZE m_drag_size;       // ドラッグ中の矩形サイズ
    POINT m_cursor_offset;  // ドラッグ中の矩形位置のマウス位置との差分
    HBRUSH m_desk_old_brush;    // デスクトップDC・ブラシ
    HBRUSH m_half_tone_brush;   // ハーフトーン・ブラシ

    DOCK_CONTEXT();     // コンストラクタ
    ~DOCK_CONTEXT();    // デストラクタ
    void start_drag(HWND hwnd); // ドラッグ開始
    void drag();        // ドラッグ中
    void end_drag();    // ドラッグ終了
};

// ドッキング・ツールバー統括クラス
class DOCK_SYS {
    public:
    HWND m_main_frame, m_popup_frame, m_htool_bar, m_htool_bar_frame, m_hview, m_hdock_bar; // 各HWND
    int m_now_nc_activing;          // WM_NCACTIVATEフラグ WM_NCACTIVATEの多重再送を防ぐ
    int m_floating_flag;            // フローティング・フラグ  浮いてれば==1  そうでないなら==0
    DOCK_CONTEXT m_dock_context;    // ドック・コンテキスト・構造体

    regist_winc(char *caption, HBRUSH hbr_bg, WNDPROC proc);    // ウィンドウクラス登録
    create(HWND main_hwnd, HWND child_view_hwnd);   // 生成
    void on_ncactivate(HWND hwnd, WPARAM wp);       // WM_NCACTIVATE 処理
    void do_dock();                 // ドッキング実行
    void do_float(int x, int y);    // フローティング実行
    void recalc_layout();           // 子ウィンドウ位置再計算
    void tool_on_lbuttondown(HWND hwnd); // ツールバー・マウス左ボタン押下
    void tool_on_lbuttonup();            // ツールバー・マウス左ボタン押上
    void tool_on_mousemove();            // ツールバー・マウス移動

     // ポップアップ・フレーム・プロシージャ
    PopupProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
    static LRESULT CALLBACK StaticPopupProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);

     // ツールバー・プロシージャ
    ToolBarFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
    static LRESULT CALLBACK StaticToolBarFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
} ;

// コンストラクタ
DOCK_CONTEXT::DOCK_CONTEXT(){
    WORD gray_pattern[8];
    HBITMAP gray_bitmap;
    int i;

    m_now_dragging=0;

    // ハーフトーン・パレット生成
    for (i=0;i<8;i++) gray_pattern[i] = (WORD)(0x5555 << (i & 1));  // 0x5555 は2bitで  01010101 01010101
    gray_bitmap = CreateBitmap(8, 8, 1, 1, &gray_pattern);
    if (gray_bitmap != NULL) {
        m_half_tone_brush = ::CreatePatternBrush(gray_bitmap);
        DeleteObject(gray_bitmap);
    }
}
// デストラクタ
DOCK_CONTEXT::~DOCK_CONTEXT(){
    DeleteObject(m_half_tone_brush); // ハーフトーン・パレット破棄
}
// ドラッグ開始
void DOCK_CONTEXT::start_drag(HWND hwnd){
    HWND desk_hwnd;
    RECT rc;
    m_now_dragging=1;
    SetCapture(hwnd);
    // デスクトップDCを得る
    desk_hwnd=GetDesktopWindow();
    LockWindowUpdate(desk_hwnd);
    m_desk_hdc= GetDCEx(desk_hwnd, NULL, DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
    m_desk_old_brush=(HBRUSH)SelectObject(m_desk_hdc, m_half_tone_brush);

    // ドラッグ・サイズとマウスとの座標差
    GetWindowRect(hwnd, &rc);
    m_drag_size.cx = rc.right-rc.left;
    m_drag_size.cy = rc.bottom-rc.top;

    GetCursorPos(&m_cursor_offset);
    m_cursor_offset.x -= rc.left;
    m_cursor_offset.y -= rc.top;

    // リージョン生成
    m_apply_rgn = CreateRectRgn(0, 0, 0, 0);
    m_work_rgn  = CreateRectRgn(0, 0, 0, 0);
    m_work_rgn2 = CreateRectRgn(0, 0, 0, 0);
    m_last_rgn  = CreateRectRgn(0, 0, 0, 0);
}
// ドラッグ中
void DOCK_CONTEXT::drag(){
    POINT po;
    RECT rc;
    GetCursorPos(&po);
    po.x-=m_cursor_offset.x;
    po.y-=m_cursor_offset.y;
    SetRectRgn(m_work_rgn,  po.x, po.y, po.x+m_drag_size.cx, po.y+m_drag_size.cy);
    SetRectRgn(m_work_rgn2, po.x+4, po.y+4, po.x+m_drag_size.cx-4, po.y+m_drag_size.cy-4);
    CombineRgn(m_apply_rgn, m_work_rgn, m_work_rgn2, RGN_XOR);

    CombineRgn(m_work_rgn, m_apply_rgn, m_last_rgn, RGN_XOR);

    // 反転による矩形描画
    GetRgnBox(m_work_rgn, &rc);
    SelectObject(m_desk_hdc, m_work_rgn);
    PatBlt(m_desk_hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, PATINVERT);

    // 最後に描画した部分保持(再反転して消去)
    CombineRgn(m_last_rgn, m_apply_rgn, NULL, RGN_COPY);
}
// ドラッグ終了
void DOCK_CONTEXT::end_drag(){
    RECT rc;
    m_now_dragging=0;
    ReleaseCapture();

    // 最後に描画した部分を消去(再反転してるだけ)
    GetRgnBox(m_apply_rgn, &rc);
    SelectObject(m_desk_hdc, m_apply_rgn);
    PatBlt(m_desk_hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, PATINVERT);

    // リージョン破棄
    DeleteObject(m_apply_rgn);
    DeleteObject(m_work_rgn);
    DeleteObject(m_work_rgn2);
    DeleteObject(m_last_rgn);

    // デスクトップDCを解放
    LockWindowUpdate(NULL);
    if (m_desk_hdc) ReleaseDC(GetDesktopWindow(), m_desk_hdc);
    SelectObject(m_desk_hdc, m_desk_old_brush);
}
// ポップアップウィンドウ・プロシージャ(static版)
LRESULT CALLBACK DOCK_SYS::StaticPopupProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    DOCK_SYS *p_dock_sys =(DOCK_SYS*)GetWindowLong(hwnd, GWL_USERDATA);
    if (!p_dock_sys && (msg==WM_NCCREATE || msg==WM_CREATE)){
        p_dock_sys = (DOCK_SYS*)((LPCREATESTRUCT)lp)->lpCreateParams;
        SetWindowLong(hwnd, GWL_USERDATA, (LONG)p_dock_sys);
    }
    if (p_dock_sys) return p_dock_sys->PopupProc(hwnd, msg, wp, lp);
    return DefWindowProc(hwnd, msg, wp, lp);
}
// ポップアップウィンドウ・プロシージャ
DOCK_SYS::PopupProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    int res;
    switch (msg) {
    case WM_NCACTIVATE: // タイトルバーのアクティブ化・非アクティブ化
        on_ncactivate(hwnd, wp);
        break;
    case WM_LBUTTONDOWN:
        tool_on_lbuttondown(hwnd);  // ドラッグ開始
        break;
    case WM_LBUTTONUP:
        tool_on_lbuttonup();    // ドラッグ終了
        break;
    case WM_MOUSEMOVE:
        tool_on_mousemove();    // マウス移動(ドラッグ中)
        break;
    case WM_NCHITTEST:
        res=DefWindowProc(hwnd, msg, wp, lp);
        if (res==HTCAPTION) return HTCLIENT;
        return res;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}
// ツールバーのフレームウィンドウ・プロシージャ(static版)
LRESULT CALLBACK DOCK_SYS::StaticToolBarFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp){
    DOCK_SYS *p_dock_sys =(DOCK_SYS*)GetWindowLong(hwnd, GWL_USERDATA);
    if (!p_dock_sys && (msg==WM_NCCREATE || msg==WM_CREATE)){
        p_dock_sys = (DOCK_SYS*)((LPCREATESTRUCT)lp)->lpCreateParams;
        SetWindowLong(hwnd, GWL_USERDATA, (LONG)p_dock_sys);
    }
    if (p_dock_sys) return p_dock_sys->ToolBarFrameProc(hwnd, msg, wp, lp);
    return DefWindowProc(hwnd, msg, wp, lp);
}
// ツールバーのフレームウィンドウ・プロシージャ
DOCK_SYS::ToolBarFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    RECT rc, rc2;
    HDC hdc;
    PAINTSTRUCT ps;
    switch (msg) {
    case WM_CREATE:
        InitCommonControls();
        m_htool_bar = CreateToolbarEx( hwnd, WS_CHILD | WS_VISIBLE | TBSTYLE_AUTOSIZE, 0, 6, 
            (HINSTANCE)HINST_COMMCTRL, IDB_STD_SMALL_COLOR, tool_bar_buttons, 7, 0, 0, 0, 0, sizeof (TBBUTTON)
        );
        GetWindowRect(m_htool_bar, &rc);
        SetWindowPos(hwnd, NULL, 0,0, rc.right-rc.left, rc.bottom-rc.top, SWP_NOMOVE);
        break;
    case WM_PAINT:
        hdc = BeginPaint(hwnd , &ps);
        GetClientRect(hwnd, &rc);

        rc.left=0; rc.top=0; rc.bottom=1;   FillRect(hdc, &rc, GetSysColorBrush(COLOR_BTNSHADOW));
        rc.top++;   rc.bottom++;            FillRect(hdc, &rc, GetSysColorBrush(COLOR_BTNHILIGHT));

        if (!m_floating_flag){
            // グリッパー描画
            GetClientRect(hwnd, &rc);
            rc.left+=2; rc.right=rc.left+3;
            rc.top+=1;  rc.bottom-=2;

            rc2.left=rc.left;       rc2.top=rc.top; 
            rc2.right=rc.right-1;   rc2.bottom=rc.top+1;    FillRect(hdc, &rc2, GetSysColorBrush(COLOR_BTNHILIGHT));
            rc2.right=rc.left+1;    rc2.bottom=rc.bottom-1; FillRect(hdc, &rc2, GetSysColorBrush(COLOR_BTNHILIGHT));

            rc2.left=rc.right;      rc2.top=rc.top;
            rc2.right=rc.right-1;   rc2.bottom=rc.bottom;   FillRect(hdc, &rc2, GetSysColorBrush(COLOR_BTNSHADOW));
            rc2.left=rc.left;       rc2.top=rc.bottom;
            rc2.right=rc.right;     rc2.bottom=rc.bottom-1; FillRect(hdc, &rc2, GetSysColorBrush(COLOR_BTNSHADOW));
        }
        EndPaint(hwnd , &ps);
        break;
    case WM_SIZE:
        SendMessage(m_htool_bar, WM_SIZE, wp, lp);  // ツーバーのリサイズ
        if (!m_floating_flag) SetWindowPos(m_htool_bar, NULL, 10,0, LOWORD(lp),HIWORD(lp), 0);
        break;
    case WM_LBUTTONDOWN:    // マウス左ボタン押上(ドラッグ終了)
        tool_on_lbuttondown(hwnd);
        break;
    case WM_LBUTTONUP:      // マウス左ボタン押上(ドラッグ開始)
        tool_on_lbuttonup();
        break;
    case WM_MOUSEMOVE:      // マウス移動(ドラッグ中)
        tool_on_mousemove();
        break;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}

// マウス移動
void DOCK_SYS::tool_on_mousemove(){
    if (!m_dock_context.m_now_dragging) return;
    m_dock_context.drag();  // ドラッグ中
}
// マウス左ボタン押上
void DOCK_SYS::tool_on_lbuttondown(HWND hwnd){
    if (m_dock_context.m_now_dragging) return;
    m_dock_context.start_drag(hwnd);    // ドラッグ開始
}
// マウス左ボタン押上
void DOCK_SYS::tool_on_lbuttonup(){
    RECT drag_rc, dock_rc;
    if (!m_dock_context.m_now_dragging) return;
    m_dock_context.end_drag();  // ドラッグ終了

    // ドッキング・フローティング判定
    GetWindowRect(m_hdock_bar, &dock_rc);
    POINT po;
    GetCursorPos((POINT*)&po);
    drag_rc.left=po.x-m_dock_context.m_cursor_offset.x;
    drag_rc.top =po.y-m_dock_context.m_cursor_offset.y;
    drag_rc.right = drag_rc.left   + m_dock_context.m_drag_size.cx;
    drag_rc.bottom= drag_rc.top + m_dock_context.m_drag_size.cy;

    // ドッキング判定
    if (drag_rc.left<=dock_rc.right && drag_rc.right>=dock_rc.left
            && drag_rc.top<=dock_rc.bottom && drag_rc.bottom>=dock_rc.top){
        do_dock();
    }
    // フローティング判定
    else do_float(drag_rc.left, drag_rc.top);
}
// ドッキングシステム生成
DOCK_SYS::create(HWND main_hwnd, HWND child_view_hwnd){
    m_now_nc_activing=0;
    m_floating_flag=0;
    m_main_frame=main_hwnd;
    m_hview=child_view_hwnd;

    regist_winc(TEXT("popup_frame"),    (HBRUSH)(COLOR_BTNFACE+1), StaticPopupProc);        // フローティング・フレーム
    regist_winc(TEXT("tool_bar_frame"), (HBRUSH)(COLOR_BTNFACE+1), StaticToolBarFrameProc); // ツールバーの外枠
    regist_winc(TEXT("dock_bar_frame"), (HBRUSH)(COLOR_BTNFACE+1), DefWindowProc);          // ドックバー

    HINSTANCE hInstance=GetModuleHandle(NULL);
    m_popup_frame= CreateWindowEx(
        WS_EX_TOOLWINDOW, TEXT("popup_frame"), NULL, WS_OVERLAPPEDWINDOW | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        300, 170, 200, 100, main_hwnd, NULL, hInstance, (LPVOID)this
    );
    m_htool_bar_frame= CreateWindow(
        TEXT("tool_bar_frame"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0, 0, 200, 100, main_hwnd, NULL, hInstance, (LPVOID)this
    );
    m_hdock_bar = CreateWindow(
        TEXT("dock_bar_frame"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0, 0, 200, 100, main_hwnd, NULL, hInstance, (LPVOID)this
    );
    do_dock();
}
// タイトルバーのアクティブ化・非アクティブ化
void DOCK_SYS::on_ncactivate(HWND hwnd, WPARAM wp){
    if (m_now_nc_activing) return;
    m_now_nc_activing=1;
    SendMessage(m_main_frame, WM_NCACTIVATE, wp, 0);
    SendMessage(m_popup_frame, WM_NCACTIVATE, wp, 0);
    m_now_nc_activing=0;
}

// ドッキング
void DOCK_SYS::do_dock(){
    SetWindowPos(m_htool_bar_frame, NULL, 0,0, 0,0, SWP_NOSIZE);
    if (!m_floating_flag) return;
    SetParent(m_htool_bar_frame, m_hdock_bar);
    m_floating_flag = 0;
    ShowWindow(m_popup_frame, SW_HIDE);
    recalc_layout();
}

// フローティング
void DOCK_SYS::do_float(int x, int y){
    SetWindowPos(m_popup_frame, NULL, x, y, 0,0, SWP_NOSIZE);

    if (m_floating_flag) return;
    SetParent(m_htool_bar_frame, m_popup_frame);
    m_floating_flag = 1;
    SetWindowPos(m_htool_bar_frame, NULL, 0,0, 0,0, SWP_NOSIZE);
    ShowWindow(m_popup_frame, SW_SHOW);
    recalc_layout();
}
// レイアウト再計算
void DOCK_SYS::recalc_layout(){
    if (IsIconic(m_main_frame)) return;
    RECT rc;
    SIZE tool_size;
    // 子ウィンドウ位置の再計算
    SendMessage(m_htool_bar, TB_GETMAXSIZE, 0, (LPARAM)&tool_size);     // ツールバー・サイズ取得
    DWORD padding=SendMessage(m_htool_bar, TB_GETPADDING, 0, 0);
    tool_size.cx+=LOWORD(padding);
    tool_size.cy+=HIWORD(padding);

    GetClientRect(m_main_frame, &rc);
    if (!m_floating_flag) rc.top =tool_size.cy;

    // ビューウィンドウ位置サイズ
    if (IsWindow(m_hview)) SetWindowPos(m_hview, NULL, rc.left, rc.top, rc.right, rc.bottom-rc.top, 0);

    // ドックバー位置サイズ
    SetWindowPos(m_hdock_bar, NULL, 0, 0, rc.right, rc.top, 0);

    // ポップアップ・ウィンドウ位置サイズ
    if(m_floating_flag){
        rc.left=rc.top=0;
        rc.right=tool_size.cx;
        rc.bottom=tool_size.cy;
        AdjustWindowRectEx(&rc, GetWindowLong(m_popup_frame, GWL_STYLE), FALSE, GetWindowLong(m_popup_frame, GWL_EXSTYLE));
        SetWindowPos(m_popup_frame, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top, SWP_NOMOVE);
    }

    // ツールバー横サイズ補正
    GetClientRect(GetParent(m_htool_bar_frame), &rc);
    SetWindowPos(m_htool_bar_frame, NULL, 0, 0, rc.right, tool_size.cy, 0);
}
// ウィンドウクラス登録
DOCK_SYS::regist_winc(char *caption, HBRUSH hbr_bg, WNDPROC proc){
    WNDCLASS winc;

    winc.style              = CS_HREDRAW | CS_VREDRAW;
    winc.lpfnWndProc        = proc;
    winc.cbClsExtra = winc.cbWndExtra       = 0;
    winc.hInstance          = GetModuleHandle(NULL);
    winc.hIcon              = LoadIcon(NULL, IDI_APPLICATION);
    winc.hCursor            = LoadCursor(NULL, IDC_ARROW);
    winc.hbrBackground      = hbr_bg;
    winc.lpszMenuName       = NULL;
    winc.lpszClassName      = caption;

    if (!RegisterClass(&winc)) return -1;
    return 0;
}

//======================================================================================
//============ 以下  メインウィンドウ ・ ビューウィンドウ ==============================
//======================================================================================

// ビューウィンドウ・プロシージャ
LRESULT CALLBACK ChildViewProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    HDC hdc;
    PAINTSTRUCT ps;
    char str[]="ChildViewウィンドウ(座標0,0)";

    switch (msg) {
    case WM_LBUTTONDOWN:
        SendMessage(GetParent(hwnd), WM_LBUTTONDOWN, wp, lp);
        break;
    case WM_PAINT:
        hdc = BeginPaint(hwnd , &ps);
        TextOut(hdc, 0, 0, str, lstrlen(str));
        EndPaint(hwnd , &ps);
        break;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}
// メインウィンドウ・プロシージャ
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    static DOCK_SYS dock_sys;   // ウィンドウ・ハンドルの一括化 構造体
    static HWND hview;

    switch (msg) {
    case WM_CREATE:
        hview= CreateWindowEx(
            WS_EX_TOOLWINDOW, TEXT("child_view"), NULL, WS_CHILD | WS_VISIBLE,
            0, 0, 200, 100, hwnd, NULL, ((LPCREATESTRUCT)(lp))->hInstance, NULL
        );
        dock_sys.create(hwnd, hview);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_NCACTIVATE: // タイトルバーのアクティブ化・非アクティブ化
        dock_sys.on_ncactivate(hwnd, wp);
        break;
    case WM_SIZE:
        dock_sys.recalc_layout();
        break;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow ) {
    MSG msg;
    WNDCLASS winc;
    HWND hwnd;

    winc.style              = CS_HREDRAW | CS_VREDRAW;
    winc.lpfnWndProc        = WndProc;
    winc.cbClsExtra = winc.cbWndExtra       = 0;
    winc.hInstance          = hInstance;
    winc.hIcon              = LoadIcon(NULL, IDI_APPLICATION);
    winc.hCursor            = LoadCursor(NULL, IDC_ARROW);
    winc.hbrBackground      = (HBRUSH)GetStockObject(WHITE_BRUSH);
    winc.lpszMenuName       = NULL;
    winc.lpszClassName      = TEXT("main_frame");

    if (!RegisterClass(&winc)) return -1;   // メイン・ウィンドウ

    winc.hbrBackground      = (HBRUSH)GetStockObject(WHITE_BRUSH);
    winc.lpfnWndProc        = ChildViewProc;
    winc.lpszClassName      = TEXT("child_view");
    if (!RegisterClass(&winc)) return -1;   // ビューウィンドウ

    hwnd = CreateWindow(
        TEXT("main_frame"), TEXT("ドッキング・ツールバーのテスト"),
        WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
        100, 100, 240, 200, NULL, NULL, hInstance, NULL
    );

    if (hwnd == NULL) return -1;

    while(GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
    }

    return msg.wParam;
}







上記のソースはツールバーもドックバーもごちゃまぜなので
もうちょっとクラス化して下記でTOOL_BARクラスとDOCK_BARクラスを作っています。
動作は全く同じです。

docking_test3_2.cpp

#define _WIN32_IE 0x0501
#include <windows.h>
#include <commctrl.h>

// ドック・コンテキスト・構造体
class DOCK_CONTEXT {
    public:
    HRGN m_apply_rgn, m_work_rgn, m_work_rgn2, m_last_rgn;  // リージョン
    HDC m_desk_hdc;         // デスクトップDC
    int m_now_dragging;     // ドラッグ中なら==1  そうでないなら==0
    SIZE m_drag_size;       // ドラッグ中の矩形サイズ
    POINT m_cursor_offset;  // ドラッグ中の矩形位置のマウス位置との差分
    HBRUSH m_desk_old_brush;    // デスクトップDC・ブラシ
    HBRUSH m_half_tone_brush;   // ハーフトーン・ブラシ

    DOCK_CONTEXT();     // コンストラクタ
    ~DOCK_CONTEXT();    // デストラクタ
    void start_drag(HWND hwnd); // ドラッグ開始
    void drag();        // ドラッグ中
    void end_drag();    // ドラッグ終了
};
// クラスの仮宣言
class DOCK_SYS;

// ツールバークラス
class TOOL_BAR {
    public:
    HWND m_hwnd, m_control_tool_bar, m_popup_frame; // 各HWND
    DOCK_SYS *m_p_dock_sys;     // ドッキング・ツールバー統括クラス・ポインタ
    int m_floating_flag;            // フローティング・フラグ  浮いてれば==1  そうでないなら==0

    create(DOCK_SYS *p_dock_sys, TBBUTTON *tb_buttons, int tb_button_len);  // ツールバー生成

     // ポップアップ・フレーム・プロシージャ
    PopupProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
    static LRESULT CALLBACK StaticPopupProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);

     // ツールバー・プロシージャ
    ToolBarFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
    static LRESULT CALLBACK StaticToolBarFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
};
// ドックバークラス
class DOCK_BAR {
    public:
    HWND m_hwnd;
};

// ドッキング・ツールバー統括クラス
class DOCK_SYS {
    public:
    HWND m_main_frame, m_hview;     // 各HWND
    int m_now_nc_activing;          // WM_NCACTIVATEフラグ WM_NCACTIVATEの多重再送を防ぐ
    DOCK_CONTEXT m_dock_context;    // ドック・コンテキスト・構造体

    DOCK_BAR m_dock_bar;    // ドックバークラス
    TOOL_BAR m_tool_bar;    // ツールバークラス

    regist_winc(char *caption, HBRUSH hbr_bg, WNDPROC proc);    // ウィンドウクラス登録
    create(HWND main_hwnd, HWND child_view_hwnd);   // 生成
    void on_ncactivate(HWND hwnd, WPARAM wp);       // WM_NCACTIVATE 処理
    void do_dock();                 // ドッキング実行
    void do_float(int x, int y);    // フローティング実行
    void recalc_layout();           // 子ウィンドウ位置再計算
    void tool_on_lbuttondown(HWND hwnd); // ツールバー・マウス左ボタン押下
    void tool_on_lbuttonup();            // ツールバー・マウス左ボタン押上
    void tool_on_mousemove();            // ツールバー・マウス移動
} ;

// コンストラクタ
DOCK_CONTEXT::DOCK_CONTEXT(){
    WORD gray_pattern[8];
    HBITMAP gray_bitmap;
    int i;

    m_now_dragging=0;

    // ハーフトーン・パレット生成
    for (i=0;i<8;i++) gray_pattern[i] = (WORD)(0x5555 << (i & 1));  // 0x5555 は2bitで  01010101 01010101
    gray_bitmap = CreateBitmap(8, 8, 1, 1, &gray_pattern);
    if (gray_bitmap != NULL) {
        m_half_tone_brush = ::CreatePatternBrush(gray_bitmap);
        DeleteObject(gray_bitmap);
    }
}
// デストラクタ
DOCK_CONTEXT::~DOCK_CONTEXT(){
    DeleteObject(m_half_tone_brush); // ハーフトーン・パレット破棄
}
// ドラッグ開始
void DOCK_CONTEXT::start_drag(HWND hwnd){
    HWND desk_hwnd;
    RECT rc;
    m_now_dragging=1;
    SetCapture(hwnd);
    // デスクトップDCを得る
    desk_hwnd=GetDesktopWindow();
    LockWindowUpdate(desk_hwnd);
    m_desk_hdc= GetDCEx(desk_hwnd, NULL, DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
    m_desk_old_brush=(HBRUSH)SelectObject(m_desk_hdc, m_half_tone_brush);

    // ドラッグ・サイズとマウスとの座標差
    GetWindowRect(hwnd, &rc);
    m_drag_size.cx = rc.right-rc.left;
    m_drag_size.cy = rc.bottom-rc.top;

    GetCursorPos(&m_cursor_offset);
    m_cursor_offset.x -= rc.left;
    m_cursor_offset.y -= rc.top;

    // リージョン生成
    m_apply_rgn = CreateRectRgn(0, 0, 0, 0);
    m_work_rgn  = CreateRectRgn(0, 0, 0, 0);
    m_work_rgn2 = CreateRectRgn(0, 0, 0, 0);
    m_last_rgn  = CreateRectRgn(0, 0, 0, 0);
}
// ドラッグ中
void DOCK_CONTEXT::drag(){
    POINT po;
    RECT rc;
    GetCursorPos(&po);
    po.x-=m_cursor_offset.x;
    po.y-=m_cursor_offset.y;
    SetRectRgn(m_work_rgn,  po.x, po.y, po.x+m_drag_size.cx, po.y+m_drag_size.cy);
    SetRectRgn(m_work_rgn2, po.x+4, po.y+4, po.x+m_drag_size.cx-4, po.y+m_drag_size.cy-4);
    CombineRgn(m_apply_rgn, m_work_rgn, m_work_rgn2, RGN_XOR);

    CombineRgn(m_work_rgn, m_apply_rgn, m_last_rgn, RGN_XOR);

    // 反転による矩形描画
    GetRgnBox(m_work_rgn, &rc);
    SelectObject(m_desk_hdc, m_work_rgn);
    PatBlt(m_desk_hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, PATINVERT);

    // 最後に描画した部分保持(再反転して消去)
    CombineRgn(m_last_rgn, m_apply_rgn, NULL, RGN_COPY);
}
// ドラッグ終了
void DOCK_CONTEXT::end_drag(){
    RECT rc;
    m_now_dragging=0;
    ReleaseCapture();

    // 最後に描画した部分を消去(再反転してるだけ)
    GetRgnBox(m_apply_rgn, &rc);
    SelectObject(m_desk_hdc, m_apply_rgn);
    PatBlt(m_desk_hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, PATINVERT);

    // リージョン破棄
    DeleteObject(m_apply_rgn);
    DeleteObject(m_work_rgn);
    DeleteObject(m_work_rgn2);
    DeleteObject(m_last_rgn);

    // デスクトップDCを解放
    LockWindowUpdate(NULL);
    if (m_desk_hdc) ReleaseDC(GetDesktopWindow(), m_desk_hdc);
    SelectObject(m_desk_hdc, m_desk_old_brush);
}
// ツールバー生成
TOOL_BAR::create(DOCK_SYS *p_dock_sys, TBBUTTON *tb_buttons, int tb_button_len){
    m_floating_flag=0;
    m_p_dock_sys=p_dock_sys;
    HINSTANCE hInstance=GetModuleHandle(NULL);
    // ポップアップ・フレーム生成
    m_popup_frame= CreateWindowEx(
        WS_EX_TOOLWINDOW, TEXT("popup_frame"), NULL, WS_OVERLAPPEDWINDOW | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        300, 170, 200, 100, p_dock_sys->m_main_frame, NULL, hInstance, (LPVOID)this
    );
    InitCommonControls();
    // コモンコントロールのツールバー生成
    m_control_tool_bar = CreateToolbarEx(p_dock_sys->m_main_frame, WS_CHILD | TBSTYLE_AUTOSIZE, 0, 6, 
        (HINSTANCE)HINST_COMMCTRL, IDB_STD_SMALL_COLOR, tb_buttons, tb_button_len, 0, 0, 0, 0, sizeof (TBBUTTON)
    );
    // ツールバーのフレーム生成
    m_hwnd= CreateWindow(
        TEXT("tool_bar_frame"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0, 0, 200, 100, p_dock_sys->m_main_frame, NULL, hInstance, (LPVOID)this
    );
    SetParent(m_control_tool_bar, m_hwnd);
    ShowWindow(m_control_tool_bar, SW_SHOWNA);
}
// ポップアップウィンドウ・プロシージャ(static版)
LRESULT CALLBACK TOOL_BAR::StaticPopupProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    TOOL_BAR *p_tool_bar =(TOOL_BAR*)GetWindowLong(hwnd, GWL_USERDATA);
    if (!p_tool_bar && (msg==WM_NCCREATE || msg==WM_CREATE)){
        p_tool_bar = (TOOL_BAR*)((LPCREATESTRUCT)lp)->lpCreateParams;
        SetWindowLong(hwnd, GWL_USERDATA, (LONG)p_tool_bar);
    }
    if (p_tool_bar) return p_tool_bar->PopupProc(hwnd, msg, wp, lp);
    return DefWindowProc(hwnd, msg, wp, lp);
}
// ポップアップウィンドウ・プロシージャ
TOOL_BAR::PopupProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    int res;
    switch (msg) {
    case WM_NCACTIVATE: // タイトルバーのアクティブ化・非アクティブ化
        m_p_dock_sys->on_ncactivate(hwnd, wp);
        break;
    case WM_LBUTTONDOWN:m_p_dock_sys->tool_on_lbuttondown(hwnd);    break;  // ドラッグ開始
    case WM_LBUTTONUP:  m_p_dock_sys->tool_on_lbuttonup();          break;  // ドラッグ終了
    case WM_MOUSEMOVE:  m_p_dock_sys->tool_on_mousemove();          break;  // マウス移動(ドラッグ中)
    case WM_NCHITTEST:
        res=DefWindowProc(hwnd, msg, wp, lp);
        if (res==HTCAPTION) return HTCLIENT;
        return res;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}
// ツールバーのフレームウィンドウ・プロシージャ(static版)
LRESULT CALLBACK TOOL_BAR::StaticToolBarFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp){
    TOOL_BAR *p_tool_bar =(TOOL_BAR*)GetWindowLong(hwnd, GWL_USERDATA);
    if (!p_tool_bar && (msg==WM_NCCREATE || msg==WM_CREATE)){
        p_tool_bar = (TOOL_BAR*)((LPCREATESTRUCT)lp)->lpCreateParams;
        SetWindowLong(hwnd, GWL_USERDATA, (LONG)p_tool_bar);
    }
    if (p_tool_bar) return p_tool_bar->ToolBarFrameProc(hwnd, msg, wp, lp);
    return DefWindowProc(hwnd, msg, wp, lp);
}
// ツールバーのフレームウィンドウ・プロシージャ
TOOL_BAR::ToolBarFrameProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    RECT rc, rc2;
    HDC hdc;
    PAINTSTRUCT ps;
    switch (msg) {
    case WM_PAINT:
        hdc = BeginPaint(hwnd , &ps);
        GetClientRect(hwnd, &rc);

        rc.left=0; rc.top=0; rc.bottom=1;   FillRect(hdc, &rc, GetSysColorBrush(COLOR_BTNSHADOW));
        rc.top++;   rc.bottom++;            FillRect(hdc, &rc, GetSysColorBrush(COLOR_BTNHILIGHT));

        if (!m_floating_flag){
            // グリッパー描画
            GetClientRect(hwnd, &rc);
            rc.left+=2; rc.right=rc.left+3;
            rc.top+=1;  rc.bottom-=2;

            rc2.left=rc.left;       rc2.top=rc.top; 
            rc2.right=rc.right-1;   rc2.bottom=rc.top+1;    FillRect(hdc, &rc2, GetSysColorBrush(COLOR_BTNHILIGHT));
            rc2.right=rc.left+1;    rc2.bottom=rc.bottom-1; FillRect(hdc, &rc2, GetSysColorBrush(COLOR_BTNHILIGHT));

            rc2.left=rc.right;      rc2.top=rc.top;
            rc2.right=rc.right-1;   rc2.bottom=rc.bottom;   FillRect(hdc, &rc2, GetSysColorBrush(COLOR_BTNSHADOW));
            rc2.left=rc.left;       rc2.top=rc.bottom;
            rc2.right=rc.right;     rc2.bottom=rc.bottom-1; FillRect(hdc, &rc2, GetSysColorBrush(COLOR_BTNSHADOW));
        }
        EndPaint(hwnd , &ps);
        break;
    case WM_SIZE:
        SendMessage(m_control_tool_bar, WM_SIZE, wp, lp);   // ツーバーのリサイズ
        if (!m_floating_flag) SetWindowPos(m_control_tool_bar, NULL, 10,0, LOWORD(lp),HIWORD(lp), 0);
        break;
    case WM_LBUTTONDOWN:m_p_dock_sys->tool_on_lbuttondown(hwnd);break;  // マウス左ボタン押下(ドラッグ終了)
    case WM_LBUTTONUP:  m_p_dock_sys->tool_on_lbuttonup();      break;  // マウス左ボタン押上(ドラッグ開始)
    case WM_MOUSEMOVE:  m_p_dock_sys->tool_on_mousemove();      break;  // マウス移動(ドラッグ中)
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}

// マウス移動
void DOCK_SYS::tool_on_mousemove(){
    if (!m_dock_context.m_now_dragging) return;
    m_dock_context.drag();  // ドラッグ中
}
// マウス左ボタン押下
void DOCK_SYS::tool_on_lbuttondown(HWND hwnd){
    if (m_dock_context.m_now_dragging) return;
    m_dock_context.start_drag(hwnd);    // ドラッグ開始
}
// マウス左ボタン押上
void DOCK_SYS::tool_on_lbuttonup(){
    RECT drag_rc, dock_rc;
    if (!m_dock_context.m_now_dragging) return;
    m_dock_context.end_drag();  // ドラッグ終了

    // ドッキング・フローティング判定
    POINT po;
    GetCursorPos(&po);
    drag_rc.left=po.x-m_dock_context.m_cursor_offset.x;
    drag_rc.top =po.y-m_dock_context.m_cursor_offset.y;
    drag_rc.right = drag_rc.left   + m_dock_context.m_drag_size.cx;
    drag_rc.bottom= drag_rc.top + m_dock_context.m_drag_size.cy;

    GetWindowRect(m_dock_bar.m_hwnd, &dock_rc);
    // ドッキング判定
    if (drag_rc.left<=dock_rc.right && drag_rc.right>=dock_rc.left
            && drag_rc.top<=dock_rc.bottom && drag_rc.bottom>=dock_rc.top){
        do_dock();
    }
    // フローティング判定
    else do_float(drag_rc.left, drag_rc.top);
}
// ドッキングシステム生成
DOCK_SYS::create(HWND main_hwnd, HWND child_view_hwnd){
    m_now_nc_activing=0;
    m_main_frame=main_hwnd;
    m_hview=child_view_hwnd;

    regist_winc(TEXT("popup_frame"),    (HBRUSH)(COLOR_BTNFACE+1), TOOL_BAR::StaticPopupProc);      // フローティング・フレーム
    regist_winc(TEXT("tool_bar_frame"), (HBRUSH)(COLOR_BTNFACE+1), TOOL_BAR::StaticToolBarFrameProc); // ツールバーの外枠
    regist_winc(TEXT("dock_bar_frame"), (HBRUSH)(COLOR_BTNFACE+1), DefWindowProc);          // ドックバー

    HINSTANCE hInstance=GetModuleHandle(NULL);
    m_dock_bar.m_hwnd = CreateWindow(
        TEXT("dock_bar_frame"), NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0, 0, 200, 100, main_hwnd, NULL, hInstance, (LPVOID)this
    );

    // ツールバーの生成
    TBBUTTON tool_bar_buttons[] = {
        { STD_FILENEW, 1, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
        { STD_FILEOPEN, 2, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
        { STD_FILESAVE, 3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
        { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0 },
        { STD_COPY, 4, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
        { STD_CUT, 5, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
        { STD_DELETE, 6, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
        { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0 },
        { VIEW_NEWFOLDER, 7, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
        { VIEW_PARENTFOLDER, 8, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0 },
    };
    m_tool_bar.create(this, tool_bar_buttons, 7);
    do_dock();
}
// タイトルバーのアクティブ化・非アクティブ化
void DOCK_SYS::on_ncactivate(HWND hwnd, WPARAM wp){
    if (m_now_nc_activing) return;
    m_now_nc_activing=1;
    SendMessage(m_main_frame, WM_NCACTIVATE, wp, 0);
    SendMessage(m_tool_bar.m_popup_frame, WM_NCACTIVATE, wp, 0);
    m_now_nc_activing=0;
}

// ドッキング
void DOCK_SYS::do_dock(){
    SetParent(m_tool_bar.m_hwnd, m_dock_bar.m_hwnd);
    m_tool_bar.m_floating_flag = 0;
    ShowWindow(m_tool_bar.m_popup_frame, SW_HIDE);
    recalc_layout();
}

// フローティング
void DOCK_SYS::do_float(int x, int y){
    SetWindowPos(m_tool_bar.m_popup_frame, NULL, x, y, 0,0, SWP_NOSIZE);

    if (m_tool_bar.m_floating_flag) return;
    SetParent(m_tool_bar.m_hwnd, m_tool_bar.m_popup_frame);
    m_tool_bar.m_floating_flag = 1;
    ShowWindow(m_tool_bar.m_popup_frame, SW_SHOW);
    recalc_layout();
}
// レイアウト再計算
void DOCK_SYS::recalc_layout(){
    if (IsIconic(m_main_frame)) return;
    RECT rc;
    SIZE tool_size;
    // 子ウィンドウ位置の再計算
    SendMessage(m_tool_bar.m_control_tool_bar, TB_GETMAXSIZE, 0, (LPARAM)&tool_size);   // ツールバー・サイズ取得
    DWORD padding=SendMessage(m_tool_bar.m_control_tool_bar, TB_GETPADDING, 0, 0);
    tool_size.cx+=LOWORD(padding);
    tool_size.cy+=HIWORD(padding);

    GetClientRect(m_main_frame, &rc);
    if (!m_tool_bar.m_floating_flag) rc.top =tool_size.cy;

    // ビューウィンドウ位置サイズ
    if (IsWindow(m_hview)) SetWindowPos(m_hview, NULL, rc.left, rc.top, rc.right, rc.bottom-rc.top, 0);

    // ドックバー位置サイズ
    SetWindowPos(m_dock_bar.m_hwnd, NULL, 0, 0, rc.right, rc.top, 0);

    // ポップアップ・ウィンドウ位置サイズ
    if(m_tool_bar.m_floating_flag){
        rc.left=rc.top=0;
        rc.right=tool_size.cx;
        rc.bottom=tool_size.cy;
        AdjustWindowRectEx(&rc, GetWindowLong(m_tool_bar.m_popup_frame, GWL_STYLE),
                    FALSE, GetWindowLong(m_tool_bar.m_popup_frame, GWL_EXSTYLE));
        SetWindowPos(m_tool_bar.m_popup_frame, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top, SWP_NOMOVE);
    }

    // ツールバー横サイズ補正
    GetClientRect(GetParent(m_tool_bar.m_hwnd), &rc);
    SetWindowPos(m_tool_bar.m_hwnd, NULL, 0, 0, rc.right, tool_size.cy, 0);
}
// ウィンドウクラス登録
DOCK_SYS::regist_winc(char *caption, HBRUSH hbr_bg, WNDPROC proc){
    WNDCLASS winc;

    winc.style              = CS_HREDRAW | CS_VREDRAW;
    winc.lpfnWndProc        = proc;
    winc.cbClsExtra = winc.cbWndExtra       = 0;
    winc.hInstance          = GetModuleHandle(NULL);
    winc.hIcon              = LoadIcon(NULL, IDI_APPLICATION);
    winc.hCursor            = LoadCursor(NULL, IDC_ARROW);
    winc.hbrBackground      = hbr_bg;
    winc.lpszMenuName       = NULL;
    winc.lpszClassName      = caption;

    if (!RegisterClass(&winc)) return -1;
    return 0;
}

//======================================================================================
//============ 以下  メインウィンドウ ・ ビューウィンドウ ==============================
//======================================================================================

// ビューウィンドウ・プロシージャ
LRESULT CALLBACK ChildViewProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    HDC hdc;
    PAINTSTRUCT ps;
    char str[]="ChildViewウィンドウ(座標0,0)";

    switch (msg) {
    case WM_LBUTTONDOWN:
        SendMessage(GetParent(hwnd), WM_LBUTTONDOWN, wp, lp);
        break;
    case WM_PAINT:
        hdc = BeginPaint(hwnd , &ps);
        TextOut(hdc, 0, 0, str, lstrlen(str));
        EndPaint(hwnd , &ps);
        break;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}
// メインウィンドウ・プロシージャ
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    static DOCK_SYS dock_sys;   // ウィンドウ・ハンドルの一括化 構造体
    static HWND hview;

    switch (msg) {
    case WM_CREATE:
        hview= CreateWindowEx(
            WS_EX_TOOLWINDOW, TEXT("child_view"), NULL, WS_CHILD | WS_VISIBLE,
            0, 0, 200, 100, hwnd, NULL, ((LPCREATESTRUCT)(lp))->hInstance, NULL
        );
        dock_sys.create(hwnd, hview);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_NCACTIVATE: // タイトルバーのアクティブ化・非アクティブ化
        dock_sys.on_ncactivate(hwnd, wp);
        break;
    case WM_SIZE:
        dock_sys.recalc_layout();
        break;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow ) {
    MSG msg;
    WNDCLASS winc;
    HWND hwnd;

    winc.style              = CS_HREDRAW | CS_VREDRAW;
    winc.lpfnWndProc        = WndProc;
    winc.cbClsExtra = winc.cbWndExtra       = 0;
    winc.hInstance          = hInstance;
    winc.hIcon              = LoadIcon(NULL, IDI_APPLICATION);
    winc.hCursor            = LoadCursor(NULL, IDC_ARROW);
    winc.hbrBackground      = (HBRUSH)GetStockObject(WHITE_BRUSH);
    winc.lpszMenuName       = NULL;
    winc.lpszClassName      = TEXT("main_frame");

    if (!RegisterClass(&winc)) return -1;   // メイン・ウィンドウ

    winc.hbrBackground      = (HBRUSH)GetStockObject(WHITE_BRUSH);
    winc.lpfnWndProc        = ChildViewProc;
    winc.lpszClassName      = TEXT("child_view");
    if (!RegisterClass(&winc)) return -1;   // ビューウィンドウ

    hwnd = CreateWindow(
        TEXT("main_frame"), TEXT("ドッキング・ツールバーのテスト"),
        WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
        100, 100, 240, 200, NULL, NULL, hInstance, NULL
    );

    if (hwnd == NULL) return -1;

    while(GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
    }

    return msg.wParam;
}


 004-02  前へ←  ホームへ  →次へ  004-04