/*
 * OleView (oleview.c)
 *
 * Copyright 2006 Piotr Caban
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "main.h"

GLOBALS globals;
static WCHAR wszRegEdit[] = { 'r','e','g','e','d','i','t','.','e','x','e','\0' };
static WCHAR wszFormat[] = { '<','o','b','j','e','c','t','\n',' ',' ',' ',
    'c','l','a','s','s','i','d','=','\"','c','l','s','i','d',':','%','s','\"','\n',
    '>','\n','<','/','o','b','j','e','c','t','>','\0' };

static INT_PTR CALLBACK SysConfProc(HWND hDlgWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HKEY hKey;
    WCHAR buffer[MAX_LOAD_STRING];
    DWORD bufSize;

    WCHAR wszReg[] = { 'S','o','f','t','w','a','r','e','\\',
        'M','i','c','r','o','s','o','f','t','\\','O','L','E','\\','\0' };
    WCHAR wszEnableDCOM[] = { 'E','n','a','b','l','e','D','C','O','M','\0' };
    WCHAR wszEnableRemote[] = { 'E','n','a','b','l','e',
        'R','e','m','o','t','e','C','o','n','n','e','c','t','\0' };
    WCHAR wszYes[] = { 'Y', '\0' };
    WCHAR wszNo[] = { 'N', '\0' };

    switch(uMsg)
    {
        case WM_INITDIALOG:
            if(RegOpenKey(HKEY_LOCAL_MACHINE, wszReg, &hKey) != ERROR_SUCCESS)
                RegCreateKey(HKEY_LOCAL_MACHINE, wszReg, &hKey);

            bufSize = sizeof(buffer);
            if(RegGetValue(hKey, NULL, wszEnableDCOM, RRF_RT_REG_SZ,
                        NULL, buffer, &bufSize) != ERROR_SUCCESS)
            {
                bufSize = sizeof(wszYes);
                RegSetValueEx(hKey, wszEnableDCOM, 0, REG_SZ, (BYTE*)wszYes, bufSize);
            }

            CheckDlgButton(hDlgWnd, IDC_ENABLEDCOM,
                    buffer[0]=='Y' ? BST_CHECKED : BST_UNCHECKED);

            bufSize = sizeof(buffer);
            if(RegGetValue(hKey, NULL, wszEnableRemote, RRF_RT_REG_SZ,
                        NULL, buffer, &bufSize) != ERROR_SUCCESS)
            {
                bufSize = sizeof(wszYes);
                RegSetValueEx(hKey, wszEnableRemote, 0, REG_SZ, (BYTE*)wszYes, bufSize);
            }

            CheckDlgButton(hDlgWnd, IDC_ENABLEREMOTE,
                    buffer[0]=='Y' ? BST_CHECKED : BST_UNCHECKED);
            
            RegCloseKey(hKey);
            return TRUE;
        case WM_COMMAND:
            switch(LOWORD(wParam)) {
            case IDOK:
                bufSize = sizeof(wszYes);

                RegOpenKey(HKEY_LOCAL_MACHINE, wszReg, &hKey);

                RegSetValueEx(hKey, wszEnableDCOM, 0, REG_SZ,
                        IsDlgButtonChecked(hDlgWnd, IDC_ENABLEDCOM) == BST_CHECKED ?
                        (BYTE*)wszYes : (BYTE*)wszNo, bufSize);

                RegSetValueEx(hKey, wszEnableRemote, 0, REG_SZ,
                        IsDlgButtonChecked(hDlgWnd, IDC_ENABLEREMOTE) == BST_CHECKED ?
                        (BYTE*)wszYes : (BYTE*)wszNo, bufSize);

                RegCloseKey(hKey);

                EndDialog(hDlgWnd, IDOK);
                return TRUE;
            case IDCANCEL:
                EndDialog(hDlgWnd, IDCANCEL);
                return TRUE;
            }
    }

    return FALSE;
}

static INT_PTR CALLBACK CreateInstOnProc(HWND hDlgWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HWND hEdit;

    switch(uMsg)
    {
        case WM_COMMAND:
            switch(LOWORD(wParam)) {
            case IDOK:
                memset(globals.wszMachineName, 0, sizeof(WCHAR[MAX_LOAD_STRING]));
                hEdit = GetDlgItem(hDlgWnd, IDC_MACHINE);

                if (GetWindowTextLength(hEdit)>0)
                    GetWindowText(hEdit, globals.wszMachineName, MAX_LOAD_STRING);

                EndDialog(hDlgWnd, IDOK);
                return TRUE;
            case IDCANCEL:
                EndDialog(hDlgWnd, IDCANCEL);
                return TRUE;
            }
    }

    return FALSE;
}

static void InitOpenFileName(HWND hWnd, OPENFILENAME *pofn, WCHAR *wszFilter,
        WCHAR *wszTitle, WCHAR *wszFileName)
{
    memset(pofn, 0, sizeof(OPENFILENAME));
    pofn->lStructSize = sizeof(OPENFILENAME);
    pofn->hwndOwner = hWnd;
    pofn->hInstance = globals.hMainInst;

    pofn->lpstrTitle = wszTitle;
    pofn->lpstrFilter = wszFilter;
    pofn->nFilterIndex = 0;
    pofn->lpstrFile = wszFileName;
    pofn->nMaxFile = MAX_LOAD_STRING;
    pofn->Flags = OFN_HIDEREADONLY;
}

static void CopyClsid(HTREEITEM item)
{
    TVITEM tvi;

    memset(&tvi, 0, sizeof(TVITEM));
    tvi.hItem = item;
    tvi.cchTextMax = MAX_LOAD_STRING;
    SendMessage(globals.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);

    if(OpenClipboard(globals.hMainWnd) && EmptyClipboard() && tvi.lParam)
    {
        HANDLE hClipData = GlobalAlloc(GHND, sizeof(WCHAR[MAX_LOAD_STRING]));
        LPVOID pLoc = GlobalLock(hClipData);

        lstrcpyW(pLoc, ((ITEM_INFO *)tvi.lParam)->clsid);
        GlobalUnlock(hClipData);
        hClipData = SetClipboardData(CF_UNICODETEXT, hClipData);
        CloseClipboard();
    }
}

static void CopyHTMLTag(HTREEITEM item)
{
    TVITEM tvi;

    memset(&tvi, 0, sizeof(TVITEM));
    tvi.hItem = item;
    tvi.cchTextMax = MAX_LOAD_STRING;
    SendMessage(globals.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);

    if(OpenClipboard(globals.hMainWnd) && EmptyClipboard() && tvi.lParam)
    {
        HANDLE hClipData = GlobalAlloc(GHND, sizeof(WCHAR[MAX_LOAD_STRING]));
        LPVOID pLoc = GlobalLock(hClipData);
        int clsidLen = lstrlenW(((ITEM_INFO *)tvi.lParam)->clsid)-1;

        ((ITEM_INFO *)tvi.lParam)->clsid[clsidLen] = '\0';
        wsprintfW(pLoc, wszFormat, ((ITEM_INFO *)tvi.lParam)->clsid+1);
        ((ITEM_INFO *)tvi.lParam)->clsid[clsidLen] = '}';

        GlobalUnlock(hClipData);
        hClipData = SetClipboardData(CF_UNICODETEXT, hClipData);
        CloseClipboard();
    }
}

static void ResizeChild(void)
{
    RECT client, stat, tool;

    MoveWindow(globals.hStatusBar, 0, 0, 0, 0, TRUE);
    MoveWindow(globals.hToolBar, 0, 0, 0, 0, TRUE);

    if(IsWindowVisible(globals.hStatusBar))
        GetClientRect(globals.hStatusBar, &stat);
    else stat.bottom = 0;

    if(IsWindowVisible(globals.hToolBar))
    {
        GetClientRect(globals.hToolBar, &tool);
        tool.bottom += 2;
    }
    else tool.bottom = 0;

    GetClientRect(globals.hMainWnd, &client);
    MoveWindow(globals.hPaneWnd, 0, tool.bottom,
            client.right, client.bottom-tool.bottom-stat.bottom, TRUE);
}

void RefreshMenu(HTREEITEM item)
{
    TVITEM tvi;
    HTREEITEM parent;
    HMENU hMenu = GetMenu(globals.hMainWnd);

    memset(&tvi, 0, sizeof(TVITEM));
    tvi.hItem = item;
    SendMessage(globals.hTree, TVM_GETITEM, 0, (LPARAM)&tvi);

    parent = TreeView_GetParent(globals.hTree, item);

    SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_CREATEINST, FALSE);
    SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_RELEASEINST, FALSE);
    SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_VIEW, FALSE);

    if(tvi.lParam && ((ITEM_INFO *)tvi.lParam)->cFlag&SHOWALL)
    {
        EnableMenuItem(hMenu, IDM_COPYCLSID, MF_ENABLED);
        EnableMenuItem(hMenu, IDM_HTMLTAG, MF_ENABLED);
        EnableMenuItem(hMenu, IDM_VIEW, MF_GRAYED);

        if(!((ITEM_INFO *)tvi.lParam)->loaded)
        {
            EnableMenuItem(hMenu, IDM_CREATEINST, MF_ENABLED);
            EnableMenuItem(hMenu, IDM_CREATEINSTON, MF_ENABLED);
            EnableMenuItem(hMenu, IDM_RELEASEINST, MF_GRAYED);
            SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_CREATEINST, TRUE);
        }
        else 
        {
            EnableMenuItem(hMenu, IDM_CREATEINST, MF_GRAYED);
            EnableMenuItem(hMenu, IDM_CREATEINSTON, MF_GRAYED);
            EnableMenuItem(hMenu, IDM_RELEASEINST, MF_ENABLED);
            SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_RELEASEINST, TRUE);
        }
    }
    else if(tvi.lParam && 
            (((ITEM_INFO *)tvi.lParam)->cFlag&INTERFACE || parent==tree.hTL))
    {
        EnableMenuItem(hMenu, IDM_TYPEINFO, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_CREATEINST, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_CREATEINSTON, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_RELEASEINST, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_COPYCLSID, MF_ENABLED);
        EnableMenuItem(hMenu, IDM_HTMLTAG, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_VIEW, MF_ENABLED);
        SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_VIEW, TRUE);
    }
    else
    {
        EnableMenuItem(hMenu, IDM_TYPEINFO, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_CREATEINST, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_CREATEINSTON, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_RELEASEINST, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_COPYCLSID, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_HTMLTAG, MF_GRAYED);
        EnableMenuItem(hMenu, IDM_VIEW, MF_GRAYED);
    }

    if(parent==tree.hAID || parent==tree.hGBCC)
        EnableMenuItem(hMenu, IDM_COPYCLSID, MF_ENABLED);
}

static int MenuCommand(WPARAM wParam, HWND hWnd)
{
    BOOL vis;
    HTREEITEM hSelect;
    WCHAR wszAbout[MAX_LOAD_STRING];
    WCHAR wszAboutVer[MAX_LOAD_STRING];

    switch(wParam)
    {
        case IDM_ABOUT:
            LoadString(globals.hMainInst, IDS_ABOUT, wszAbout,
                    sizeof(wszAbout)/sizeof(wszAbout[0]));
            LoadString(globals.hMainInst, IDS_ABOUTVER, wszAboutVer,
                    sizeof(wszAboutVer)/sizeof(wszAboutVer[0]));
            ShellAbout(hWnd, wszAbout, wszAboutVer, NULL);
            break;
        case IDM_COPYCLSID:
            hSelect = TreeView_GetSelection(globals.hTree);
            CopyClsid(hSelect);
            break;
        case IDM_HTMLTAG:
            hSelect = TreeView_GetSelection(globals.hTree);
            CopyHTMLTag(hSelect);
            break;
        case IDM_CREATEINST:
            hSelect = TreeView_GetSelection(globals.hTree);
            CreateInst(hSelect, NULL);
            SendMessage(globals.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)hSelect);
            break;
        case IDM_CREATEINSTON:
            if(DialogBox(0, MAKEINTRESOURCE(DLG_CREATEINSTON),
                        hWnd, CreateInstOnProc) == IDCANCEL) break;
            hSelect = TreeView_GetSelection(globals.hTree);
            CreateInst(hSelect, globals.wszMachineName);
            SendMessage(globals.hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)hSelect);
            break;
        case IDM_RELEASEINST:
            hSelect = TreeView_GetSelection(globals.hTree);
            ReleaseInst(hSelect);
            RefreshMenu(hSelect);
            RefreshDetails(hSelect);
            break;
        case IDM_EXPERT:
            globals.bExpert = !globals.bExpert;
            CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
                    globals.bExpert ? MF_CHECKED : MF_UNCHECKED);
            EmptyTree();
            if(globals.bExpert) AddTreeEx();
            else AddTree();
            hSelect = TreeView_GetChild(globals.hTree, TVI_ROOT);
            SendMessage(globals.hTree, TVM_SELECTITEM, 0, (LPARAM)hSelect);
            RefreshMenu(hSelect);
            break;
        case IDM_FLAG_INSERV:
            vis = globals.dwClsCtx&CLSCTX_INPROC_SERVER;
            globals.dwClsCtx = globals.dwClsCtx&(~CLSCTX_INPROC_SERVER);
            globals.dwClsCtx = globals.dwClsCtx|((~vis)&CLSCTX_INPROC_SERVER);
            if(!globals.dwClsCtx) globals.dwClsCtx = vis;
            else CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
                    vis ? MF_UNCHECKED : MF_CHECKED);
            break;
        case IDM_FLAG_INHANDL:
            vis = globals.dwClsCtx&CLSCTX_INPROC_HANDLER;
            globals.dwClsCtx = globals.dwClsCtx&(~CLSCTX_INPROC_HANDLER);
            globals.dwClsCtx = globals.dwClsCtx|((~vis)&CLSCTX_INPROC_HANDLER);
            if(!globals.dwClsCtx) globals.dwClsCtx = vis;
            else CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
                    vis ? MF_UNCHECKED : MF_CHECKED);
            break;
        case IDM_FLAG_LOCSERV:
            vis = globals.dwClsCtx&CLSCTX_LOCAL_SERVER;
            globals.dwClsCtx = globals.dwClsCtx&(~CLSCTX_LOCAL_SERVER);
            globals.dwClsCtx = globals.dwClsCtx|((~vis)&CLSCTX_LOCAL_SERVER);
            if(!globals.dwClsCtx) globals.dwClsCtx = vis;
            else CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
                    vis ? MF_UNCHECKED : MF_CHECKED);
            break;
        case IDM_FLAG_REMSERV:
            vis = globals.dwClsCtx&CLSCTX_REMOTE_SERVER;
            globals.dwClsCtx = globals.dwClsCtx&(~CLSCTX_REMOTE_SERVER);
            globals.dwClsCtx = globals.dwClsCtx|((~vis)&CLSCTX_REMOTE_SERVER);
            if(!globals.dwClsCtx) globals.dwClsCtx = vis;
            else CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
                    vis ? MF_UNCHECKED : MF_CHECKED);
            break;
        case IDM_REFRESH:
            EmptyTree();
            if(globals.bExpert) AddTreeEx();
            else AddTree();
            hSelect = TreeView_GetChild(globals.hTree, TVI_ROOT);
            SendMessage(globals.hTree, TVM_SELECTITEM, 0, (LPARAM)hSelect);
            RefreshMenu(hSelect);
            break;
        case IDM_REGEDIT:
        {
            STARTUPINFO si;
            PROCESS_INFORMATION pi;

            memset(&si, 0, sizeof(si));
            si.cb = sizeof(si);
            CreateProcess(NULL, wszRegEdit, NULL, NULL, FALSE, 0,
                    NULL, NULL, &si, &pi);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            break;
        }
        case IDM_STATUSBAR:
            vis = IsWindowVisible(globals.hStatusBar);
            ShowWindow(globals.hStatusBar, vis ? SW_HIDE : SW_SHOW);
            CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
                    vis ? MF_UNCHECKED : MF_CHECKED);
            ResizeChild();
            break;
        case IDM_SYSCONF:
            DialogBox(0, MAKEINTRESOURCE(DLG_SYSCONF), hWnd, SysConfProc);
            break;
        case IDM_TOOLBAR:
            vis = IsWindowVisible(globals.hToolBar);
            ShowWindow(globals.hToolBar, vis ? SW_HIDE : SW_SHOW);
            CheckMenuItem(GetMenu(hWnd), LOWORD(wParam),
                    vis ? MF_UNCHECKED : MF_CHECKED);
            ResizeChild();
            break;
        case IDM_TYPELIB:
            {
            OPENFILENAME ofn;
            static WCHAR wszTitle[MAX_LOAD_STRING];
            static WCHAR wszName[MAX_LOAD_STRING];
            static WCHAR wszFilter[MAX_LOAD_STRING];

            LoadString(globals.hMainInst, IDS_OPEN, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0]));
            LoadString(globals.hMainInst, IDS_OPEN_TYPELIB_FILTER, wszFilter, sizeof(wszFilter)/sizeof(wszFilter[0]));
            InitOpenFileName(hWnd, &ofn, wszFilter, wszTitle, wszName);
            if(GetOpenFileName(&ofn)) CreateTypeLibWindow(globals.hMainInst, wszName);
            break;
            }
        case IDM_VIEW:
            hSelect = TreeView_GetSelection(globals.hTree);
            if(IsInterface(hSelect)) InterfaceViewer(hSelect);
            else CreateTypeLibWindow(globals.hMainInst, NULL);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
    }
    return 0;
}

static void UpdateStatusBar(int itemID)
{
    WCHAR info[MAX_LOAD_STRING];

    if(!LoadString(globals.hMainInst, itemID, info, sizeof(info)/sizeof(info[0])))
        LoadString(globals.hMainInst, IDS_READY, info, sizeof(info)/sizeof(info[0]));

    SendMessage(globals.hStatusBar, SB_SETTEXT, 0, (LPARAM)info);
}

static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
        WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_CREATE:
            OleInitialize(NULL);
            PaneRegisterClass();
            TypeLibRegisterClass();
            if(!CreatePanedWindow(hWnd, &globals.hPaneWnd, globals.hMainInst))
                PostQuitMessage(0);
            SetLeft(globals.hPaneWnd, CreateTreeWindow(globals.hMainInst));
            SetRight(globals.hPaneWnd, CreateDetailsWindow(globals.hMainInst));
            SetFocus(globals.hTree);
            break;
        case WM_COMMAND:
            MenuCommand(LOWORD(wParam), hWnd);
            break;
        case WM_DESTROY:
            OleUninitialize();
            EmptyTree();
            PostQuitMessage(0);
            break;
        case WM_MENUSELECT:
            UpdateStatusBar(LOWORD(wParam));
            break;
        case WM_SETFOCUS:
            SetFocus(globals.hTree);
            break;
        case WM_SIZE:
            if(wParam == SIZE_MINIMIZED) break;
            ResizeChild();
            break;
        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

static BOOL InitApplication(HINSTANCE hInst)
{
    WNDCLASS wc;
    WCHAR wszAppName[MAX_LOAD_STRING];

    LoadString(hInst, IDS_APPNAME, wszAppName, sizeof(wszAppName)/sizeof(wszAppName[0]));

    memset(&wc, 0, sizeof(WNDCLASS));
    wc.lpfnWndProc = WndProc;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName = MAKEINTRESOURCE(IDM_MENU);
    wc.lpszClassName = wszAppName;

    if(!RegisterClass(&wc))
        return FALSE;

    return TRUE;
}

static BOOL InitInstance(HINSTANCE hInst, int nCmdShow)
{
    HWND hWnd;
    WCHAR wszAppName[MAX_LOAD_STRING];
    WCHAR wszTitle[MAX_LOAD_STRING];
    TBBUTTON tB[] = {
        {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
        {0, IDM_BIND, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
        {1, IDM_TYPELIB, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
        {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
        {2, IDM_REGEDIT, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
        {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
        {3, IDM_CREATEINST, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
        {4, IDM_RELEASEINST, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0},
        {0, 0, 0, BTNS_SEP, {0, 0}, 0, 0},
        {5, IDM_VIEW, TBSTATE_ENABLED, BTNS_BUTTON, {0, 0}, 0, 0}
    };

    LoadString(hInst, IDS_APPNAME, wszAppName, sizeof(wszAppName)/sizeof(wszAppName[0]));
    LoadString(hInst, IDS_APPTITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0]));

    hWnd = CreateWindow(wszAppName, wszTitle, WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
    if(!hWnd) return FALSE;

    globals.hStatusBar = CreateStatusWindow(WS_VISIBLE|WS_CHILD,
            (LPWSTR)wszTitle, hWnd, 0);

    globals.hToolBar = CreateToolbarEx(hWnd, WS_CHILD|WS_VISIBLE, 0, 1, hInst,
            IDB_TOOLBAR, tB, 10, 16, 16, 16, 16, sizeof(TBBUTTON));
    SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_CREATEINST, FALSE);
    SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_RELEASEINST, FALSE);
    SendMessage(globals.hToolBar, TB_ENABLEBUTTON, IDM_VIEW, FALSE);

    globals.hMainWnd = hWnd;
    globals.hMainInst = hInst;
    globals.bExpert = TRUE;
    globals.dwClsCtx = CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER;

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

int APIENTRY wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
                LPWSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    HANDLE hAccelTable;
   
    if(!hPrevInst)
    {
        if(!InitApplication(hInst))
            return FALSE;
    }

    if(!InitInstance(hInst, nCmdShow))
        return FALSE;

    hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDA_OLEVIEW));

    while(GetMessage(&msg, NULL, 0, 0))
    {
        if(TranslateAccelerator(globals.hMainWnd, hAccelTable, &msg)) continue;

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}
