/*
 * 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 | OFN_ENABLESIZING;
}

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,
            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 WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR 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;
}
