#ifndef CKT_NT35
#ifdef CK_SHELL_NOTIFY
#ifdef __WATCOMC__
/* The Watcom headers need this defined for shell notifications */
#ifdef _WIN32_IE
#undef _WIN32_IE
#endif /* _WIN32_IE */
#define _WIN32_IE 0x0500
#endif /* __WATCOMC__ */
#endif /* CK_SHELL_NOTIFY */
#endif /* CKT_NT35 */

#include "kappwin.hxx"
#include "kmenu.hxx"
#include "ktoolbar.hxx"
#include "kstatus.hxx"
#include "kclient.hxx"
#include "kfontdlg.hxx"
#include "kabout.hxx"
#include "kfont.hxx"
#include "ksysmets.hxx"
#include "kszpopup.hxx"
#include "ikterm.h"
#include "ikcmd.h"
#include <stdlib.h>
#include <process.h>
#include <sys/stat.h>
#include <direct.h>
extern "C" {
    extern BYTE vmode;
    extern char exedir[];
    extern int  tt_status[];
    extern int  nt5;
};

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
KAppWin::KAppWin( K_GLOBAL* kg, int menuid, int toolbarid )
    : KWin( kg )
    , sizepop( 0 )
    , menu(0)
    , toolbar(0)
    , status(0)
    , menuId(menuid)
{
    if ( !kg->noMenuBar )
        createMenu();
#ifndef NOTOOLBAR
    if ( !kg->noToolBar )
        toolbar = new KToolBar( kg, toolbarid );
#endif
    if ( !kg->noStatus )
        status = new KStatus( kg );
    client = 0;
    wmSize = SIZE_RESTORED;
}

void KAppWin::createMenu(void)
{
    menu = new KMenu( menuId );
}

void KAppWin::destroyMenu(void)
{
    delete menu;
    menu = 0;
}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
KAppWin::~KAppWin()
{
    delete sizepop;
    delete status;
    delete toolbar;
    delete menu;
}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
void KAppWin::createWin( KWin* par )
{
    KWin::createWin( par );
}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
void KAppWin::takeFocus()
{
    if( client )
        client->takeFocus();
}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
void KAppWin::size( int width, int height )
{
    if( inCreate() )
        return;

    if ( toolbar && toolbar->isVisible() )
        toolbar->size( width, height );
    if ( status && status->isVisible() )
        status->size( width, height );

    if( client ) {
        int x, y, w, h;
        getClientCoord( x, y, w, h );
        client->size( w, h );
    }
}

/*------------------------------------------------------------------------
    determine the coordinates of the client area
------------------------------------------------------------------------*/
void KAppWin::getClientCoord( int& x, int& y, int& w, int& h )
{
    int tbh = 0, tbw = 0;
    if ( toolbar && toolbar->isVisible() )
        toolbar->getSize( tbw, tbh );

    int sth = 0, stw = 0;
    if ( status && status->isVisible() )
        status->getSize( stw, sth );

    RECT rect;
    GetClientRect( hWnd, &rect );
    x = 0;
    y = tbh - kglob->sysMets->edgeHeight();
    w = rect.right;
    h = rect.bottom - tbh - sth + kglob->sysMets->edgeHeight();
}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
Bool KAppWin::sizing( UINT fwSide, LPRECT lpr )
{
    switch( kglob->mouseEffect )
    {
        case TERM_MOUSE_CHANGE_FONT:        // change the font
            sizeFontSetDim( fwSide, lpr );
            break;

        case TERM_MOUSE_NO_EFFECT:          // limit the size
            sizeFixed( fwSide, lpr );
            break;

        case TERM_MOUSE_CHANGE_DIMENSION:   // let the window size freely
        default:
        {
            if( !sizepop ) {
                sizepop = new KSizePopup( kglob );
                sizepop->createWin( this );
            }
            int w, h;
            client->getEndSize( w, h );
            if ( tt_status[vmode] )
                h--;
            sizepop->paint( w, h );
            break;
        }
    }
    return TRUE;
}

int KAppWin::sizeFont( LPRECT lpr, int force )
{
    int diffw = 0, diffh = 0;
    RECT rect;
    if ( IsZoomed(hWnd) ) {
        GetWindowRect(GetDesktopWindow(), &rect);
    } else {
        GetWindowRect(hWnd, &rect);
    }

    if ( !force ) {
        int parw = rect.right - rect.left;
        int parh = rect.bottom - rect.top;

        diffw = (lpr->right - lpr->left) - parw;
        diffh = (lpr->bottom - lpr->top) - parh;

        if (diffw == 0 && diffh == 0)
            return 0;
    }
    
    int cliw, clih;
    client->getSize( cliw, clih );
    cliw += diffw;
    clih += diffh;

    int clientWidth = 0, clientHeight = 0;
    ::getDimensions( vmode /* client->getClientID() */, 
                     &clientWidth, &clientHeight );

    int wishFontW = (cliw / clientWidth) - (cliw % clientWidth ? 0 : 1); 
    int wishFontH = (int)(clih / clientHeight / tt_linespacing[vmode]) - (clih % clientHeight ? 0 : 1);

    if( wishFontW == 0 )
        wishFontW = -1;
    if( wishFontH == 0 )
        wishFontH = -1;

    KFont* kfont = client->getFont();

    if( !kfont->tryFont( wishFontW, wishFontH, client->hdc() ) ) {
        memcpy( lpr, &rect, sizeof(RECT) );
        return 0;
    }

    if (kfont->getFontW() == wishFontW + 1 &&
        kglob->mouseEffect == TERM_MOUSE_CHANGE_FONT) {
        // For some reason I've not been able to identify so far, certain fonts
        // get us stuck in a continuous resizing loop. If we ask for a font
        // width of 5, we're given a font width of 6 causing the window to grow.
        // Next time around, we ask for a font size of 6, and we're given 7
        // causing the window to grow again. This only happens with
        // resize-changes-font, and only with certain fonts (Cascadia Light
        // being one of them). For now this ugly workaround solves the immediate
        // problem, but the font still appears stretched horizontally. At least
        // K95 window doesn't keep growing wider which was really the main
        // problem.
        if( !kfont->tryFont( wishFontW - 1, wishFontH, client->hdc() ) ) {
            memcpy( lpr, &rect, sizeof(RECT) );
            return 0;
        }
    }

    client->setInterSpacing( kfont );
    client->fontChanged();
    setFont( kfont->getFaceName(), kfont->getFontPointsH() );

    return 1;
}

/*------------------------------------------------------------------------
    size the panel according to the font
------------------------------------------------------------------------*/
void KAppWin::sizeFontSetDim( UINT fwSide, LPRECT lpr )
{
    if (!sizeFont(lpr,0))
        return;

    // pass in FALSE to prevent the client from sizing the parent
    //
    client->setDimensions( FALSE );

    int maxw = 0, maxh = 0;
    client->getMaxpDim( maxw, maxh );

    switch( fwSide )
    {
        case WMSZ_BOTTOM:       // Bottom edge
        case WMSZ_BOTTOMRIGHT:  // Bottom-right corner
        case WMSZ_RIGHT:        // Right edge
            lpr->right = lpr->left + maxw;
            lpr->bottom = lpr->top + maxh;
            break;

        case WMSZ_TOPRIGHT:     // Top-right corner
        case WMSZ_TOP:          // Top edge
            lpr->right = lpr->left + maxw;
            lpr->top = lpr->bottom - maxh;
            break;

        case WMSZ_TOPLEFT:      // Top-left corner
            lpr->left = lpr->right - maxw;
            lpr->top = lpr->bottom - maxh;
            break;

        case WMSZ_BOTTOMLEFT:   // Bottom-left corner
        case WMSZ_LEFT:         // Left edge
            lpr->left = lpr->right - maxw;
            lpr->bottom = lpr->top + maxh;
            break;
    }

    SetWindowPos( hWnd, 0, lpr->left, lpr->top, 
                  lpr->right - lpr->left, lpr->bottom - lpr->top, 
                  SWP_NOZORDER );
    client->paint();
}



/*------------------------------------------------------------------------
    prevent the user from sizing beyond the limits
------------------------------------------------------------------------*/
void KAppWin::sizeFixed( UINT fwSide, LPRECT lpr )
{
    int maxw = 0, maxh = 0;
    if( !client || !client->getMaxpDim( maxw, maxh ) )
        return;

    RECT rect;
    if ( IsZoomed(hWnd) ) {
        GetWindowRect(GetDesktopWindow(), &rect);
    } else {
        GetWindowRect(hWnd, &rect);
    }

    int w = lpr->right - lpr->left;
    int h = lpr->bottom - lpr->top;

    switch( fwSide )
    {
        case WMSZ_BOTTOM:       // Bottom edge
        case WMSZ_BOTTOMRIGHT:  // Bottom-right corner
        case WMSZ_RIGHT:        // Right edge
            if( w != maxw ) {
                lpr->left = rect.left;
                lpr->right = lpr->left + maxw;
            }
            if( h != maxh ) {
                lpr->top = rect.top;
                lpr->bottom = lpr->top + maxh;
            }
            break;

        case WMSZ_TOPRIGHT:     // Top-right corner
            if( w != maxw ) {
                lpr->left = rect.left;
                lpr->right = lpr->left + maxw;
            }
            if( h != maxh ) {
                lpr->bottom = rect.bottom;
                lpr->top = lpr->bottom - maxh;
            }
            break;

        case WMSZ_BOTTOMLEFT:   // Bottom-left corner
            if( w != maxw ) {
                lpr->right = rect.right;
                lpr->left = lpr->right - maxw;
            }
            if( h != maxh ) {
                lpr->top = rect.top;
                lpr->bottom = lpr->top + maxh;
            }
            break;

        case WMSZ_TOP:          // Top edge
        case WMSZ_TOPLEFT:      // Top-left corner
        case WMSZ_LEFT:         // Left edge
            if( w != maxw ) {
                lpr->right = rect.right;
                lpr->left = lpr->right - maxw;
            }
            if( h != maxh ) {
                lpr->bottom = rect.bottom;
                lpr->top = lpr->bottom - maxh;
            }
            break;
    }
}

/*------------------------------------------------------------------------
    prevent the user from sizing beyond the limits
------------------------------------------------------------------------*/
void KAppWin::sizeLimit( UINT fwSide, LPRECT lpr )
{
    int maxw = 0, maxh = 0;
    if( !client || !client->getMaxpDim( maxw, maxh ) )
        return;

    RECT rect;
    if ( IsZoomed(hWnd) ) {
        GetWindowRect(GetDesktopWindow(), &rect);
    } else {
        GetWindowRect(hWnd, &rect);
    }

    int w = lpr->right - lpr->left;
    int h = lpr->bottom - lpr->top;

    switch( fwSide )
    {
        case WMSZ_BOTTOM:       // Bottom edge
        case WMSZ_BOTTOMRIGHT:  // Bottom-right corner
        case WMSZ_RIGHT:        // Right edge
            if( w > maxw ) {
                lpr->left = rect.left;
                lpr->right = lpr->left + maxw;
            }
            if( h > maxh ) {
                lpr->top = rect.top;
                lpr->bottom = lpr->top + maxh;
            }
            break;

        case WMSZ_TOPRIGHT:     // Top-right corner
            if( w > maxw ) {
                lpr->left = rect.left;
                lpr->right = lpr->left + maxw;
            }
            if( h > maxh ) {
                lpr->bottom = rect.bottom;
                lpr->top = lpr->bottom - maxh;
            }
            break;

        case WMSZ_BOTTOMLEFT:   // Bottom-left corner
            if( w > maxw ) {
                lpr->right = rect.right;
                lpr->left = lpr->right - maxw;
            }
            if( h > maxh ) {
                lpr->top = rect.top;
                lpr->bottom = lpr->top + maxh;
            }
            break;

        case WMSZ_TOP:          // Top edge
        case WMSZ_TOPLEFT:      // Top-left corner
        case WMSZ_LEFT:         // Left edge
            if( w > maxw ) {
                lpr->right = rect.right;
                lpr->left = lpr->right - maxw;
            }
            if( h > maxh ) {
                lpr->bottom = rect.bottom;
                lpr->top = lpr->bottom - maxh;
            }
            break;
    }
}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
//void KAppWin::showClipboard()
//{
//	if( !OpenClipboard( hWnd ) )
//		return;
//
//	HANDLE h = GetClipboardData( CF_TEXT );
//	char* c = (char*)h;
//
//	CloseClipboard();
//}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
void KAppWin::initMenu()
{
    Bool textselected = FALSE;
    // fix-me: determine if any text has been selected
    //

    Bool clipboarddata = FALSE;
    // determine if there is any clipboard data to paste
    //
    if( OpenClipboard( hWnd ) ) {
        HANDLE h = GetClipboardData( CF_TEXT );
        char* c = (char*)h;

        CloseClipboard();
        clipboarddata = TRUE;
    }
	if (menu)
	    menu->setCopyPaste( textselected, clipboarddata );
}

void KAppWin::setKFont(KFont * f) 
{
    if ( client ) {
        client->setFont(f);
        int maxw = 0, maxh = 0;
        client->getMaxpDim( maxw, maxh );
        SetWindowPos( hWnd, 0, 0, 0, maxw, maxh
                      , SWP_NOZORDER | SWP_NOMOVE );
        client->paint();
        setFont(f->getFaceName(), f->getFontPointsH());
    }
}

static HWND se_hwnd;
static void Real_Win32ShellExecute( void * _object )
{
    HINSTANCE error;
    char * object = (char *) _object;

    error = ShellExecute(se_hwnd, 0, object, 0, 0, SW_SHOWNORMAL);

#ifdef COMMENT
    if (((DWORD)error) <= 32)
    {
        printf("%s %s %d","Win32 ShellExecute failure",object,error);
        switch ( (DWORD)error ) {
        case 0:	
            printf("%s %s %d","Win32 ShellExecute","The operating system is out of memory or resources.",0);
            break;
        case ERROR_BAD_FORMAT:
            printf("%s %s %d","Win32 ShellExecute","The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).",0);
            break;
        case SE_ERR_ACCESSDENIED:
            printf("%s %s %d","Win32 ShellExecute","The operating system denied access to the specified file.",0);
            break;
        case SE_ERR_ASSOCINCOMPLETE:
            printf("%s %s %d","Win32 ShellExecute","The filename association is incomplete or invalid.",0);
            break;
        case SE_ERR_DDEBUSY:
            printf("%s %s %d","Win32 ShellExecute","The DDE transaction could not be completed because other DDE transactions were being processed.",0);
            break;
        case SE_ERR_DDEFAIL:
            printf("%s %s %d","Win32 ShellExecute","The DDE transaction failed.",0);
            break;
        case SE_ERR_DDETIMEOUT:
            printf("%s %s %d","Win32 ShellExecute","The DDE transaction could not be completed because the request timed out.",0);
            break;
        case SE_ERR_DLLNOTFOUND:
            printf("%s %s %d","Win32 ShellExecute","The specified dynamic-link library was not found.",0);
            break;
        case SE_ERR_FNF:
            printf("%s %s %d","Win32 ShellExecute","The specified file was not found.",0);
            break;
        case SE_ERR_NOASSOC:
            printf("%s %s %d","Win32 ShellExecute","There is no application associated with the given filename extension.",0);
            break;
        case SE_ERR_OOM:
            printf("%s %s %d","Win32 ShellExecute","There was not enough memory to complete the operation.",0);
            break;
        case SE_ERR_PNF:
            printf("%s %s %d","Win32 ShellExecute","The specified path was not found.",0);
            break;
        case SE_ERR_SHARE:
            printf("%s %s %d","Win32 ShellExecute","A sharing violation occurred.",0);
            break;
        default:
            printf("%s %s %d","Win32 ShellExecute","Unknown error",0);
        }
    }
    else {
        printf("%s %s %d","Win32 ShellExecute success",object,error);
    }
#endif /* COMMENT */
    CloseHandle((HINSTANCE)error);
}

int KAppWin::Win32ShellExecute( char * object )
{
    ::se_hwnd = hwnd();
    DWORD tid = (DWORD) _beginthread( Real_Win32ShellExecute, 
                            65535, 
                            (void *)object 
                            ) ;
    return (tid != 0xffffffff);
}


int KAppWin::browse(char * url)
{
    return(Win32ShellExecute( url ));
}

int KAppWin::readManual(void)
{
    char manpath[512];
    struct stat buf;
    size_t i;

    /* Need to change directory to the DOCS\\MANUAL directory */
    /* before starting the manual.  Otherwise, Netscape may   */
    /* be unable to find the referential links.               */

    ckmakmsg(manpath,512, exedir, "DOCS\\MANUAL\\INDEX.HTM", NULL, NULL);
    for ( i=strlen(manpath); i > 0 && manpath[i] != '\\'; i-- )
        if (manpath[i] == '/')
            manpath[i] = '\\';

    if ( stat(manpath,&buf) >= 0 ) {
        int drive;
        char cwd[256], cwd2[256];

        drive = _getdrive();

        if ( drive != (tolower(manpath[0])-'a'+1) ) {
            _chdrive(tolower(manpath[0])-'a'+1);
        }
        _getcwd( cwd, 255 );

        for ( i=strlen(manpath); i > 0 && manpath[i] != '\\'; i-- );

        if ( i != 0 ) {
            manpath[i] = '\0';
            _chdir(&manpath[2]);  /* skip the drive letter */
            manpath[i] = '\\';
            _getcwd( cwd2, 255 );
        }

        browse(manpath);
        _chdir(cwd);
        _chdrive(drive);
        return(1);
    }
    return(0);
}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
#ifdef CK_SHELL_NOTIFY
/* Shell Notifications require Visual C++ 2002 (7.0) and Windows 2000
 * or newer */

/* This is new in Windows XP SP2 (Visual C++ 2008) */
#ifndef NIIF_USER
#define NIIF_USER 0x00000004
#endif

void KAppWin::showNotification( int icon, char* title, char * message ) {
    NOTIFYICONDATA nid = {sizeof(nid)};

    if (!nt5) return;  /* Notifications require Windows 2000 or newer */

    nid.hWnd = hWnd;
    nid.uID = 1;
    nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_INFO;
    nid.uCallbackMessage = WMAPP_NOTIFYCALLBACK;
    switch(icon) {
        case KUI_NOTIF_I_INFO: nid.dwInfoFlags = NIIF_INFO; break;
        case KUI_NOTIF_I_WARN: nid.dwInfoFlags = NIIF_WARNING; break;
        case KUI_NOTIF_I_ERR: nid.dwInfoFlags = NIIF_ERROR; break;
        case KUI_NOTIF_I_USER: nid.dwInfoFlags = NIIF_USER; break;
        default: nid.dwInfoFlags = NIIF_NONE; break;
    }
    strncpy(nid.szInfoTitle, title, sizeof(nid.szInfoTitle) / sizeof(nid.szInfoTitle[0]));
    strncpy(nid.szInfo, message, sizeof(nid.szInfo) / sizeof(nid.szInfo[0]));
    nid.hIcon = LoadIcon(kglob->hInst, MAKEINTRESOURCE(IDI_ICONK95));

    // If there is already a notification on screen, then a notificaiton icon
    // will already be present. We can't (and shouldn't) add another (it will
    // fail), so modify the existing one.
    if (iconCreated) {
        if (!Shell_NotifyIcon(NIM_MODIFY, &nid)) {
            iconCreated = FALSE;
        }
    }

    if (!iconCreated){
        iconCreated = Shell_NotifyIcon(NIM_ADD, &nid);
    }
}

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
void KAppWin::destroyNotificationIcon() {
    NOTIFYICONDATA nid = {sizeof(nid)};
    nid.hWnd = hWnd;
    nid.uID = 1;
    Shell_NotifyIcon(NIM_DELETE, &nid);
}

#endif /* CK_SHELL_NOTIFY */

/*------------------------------------------------------------------------
------------------------------------------------------------------------*/
Bool KAppWin::message( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    Bool done = FALSE;
    //debug(F111,"KAppWin::message","msg",msg);
    switch( msg )
    {
    case WM_ACTIVATE:
        //printf("KAppWin WM_ACTIVATE wParam=%d\n", wParam);
        //debug(F111,"KAppWin::message","WM_ACTIVATE",msg);
        if( LOWORD(wParam) != WA_INACTIVE ) {
            client->takeFocus();
            done = TRUE;
        }
        break;

    case WM_USER_SIZING:
#ifdef WM_SIZING
    case WM_SIZING:
#endif
    {
        LPRECT lpRect = (LPRECT)lParam;
        //printf("KAppWin WM_SIZING wParam=%d top=%d bottom=%d left=%d right=%d\n",
        //        wParam, lpRect->top, lpRect->bottom, lpRect->left, lpRect->right);
        //debug(F111,"KAppWin::message","WM_SIZING",msg);
        BYTE keyState[256];
        int  save = kglob->mouseEffect;
        if (GetKeyboardState(keyState)) {
            if ( (keyState[VK_CONTROL] & 128) && 
                !(keyState[VK_SHIFT] & 128) && 
                !(keyState[VK_MENU] & 128))
                kglob->mouseEffect = TERM_MOUSE_CHANGE_FONT;
            else if ( !(keyState[VK_CONTROL] & 128) && 
                      (keyState[VK_SHIFT] & 128) && 
                      !(keyState[VK_MENU] & 128))
                kglob->mouseEffect = TERM_MOUSE_CHANGE_DIMENSION;
        //    else 
        //        kglob->mouseEffect = TERM_MOUSE_NO_EFFECT;
        }
        done = sizing( (UINT)wParam, lpRect );
        kglob->mouseEffect = save;
        break;
    }

    case WM_SIZE:
        //printf("KAppWin WM_SIZE wParam=%d height=%d width=%d\n",
        //        wParam, HIWORD(lParam), LOWORD(lParam));
        //debug(F111,"KAppWin::message","WM_SIZE",msg);
        size( LOWORD(lParam), HIWORD(lParam) );
        switch ( wParam ) {
        case SIZE_RESTORED:
            if ( wmSize == SIZE_MAXIMIZED ) {
                RECT rect;
                double newLineSpacing = tt_linespacing[vmode];
                rect.top = 0;
                rect.left = 0;
                rect.bottom = HIWORD(lParam);
                rect.right = LOWORD(lParam);
                tt_linespacing[vmode] = kglob->saveLineSpacing;
                switch (kglob->saveMouseEffect) {
                case TERM_MOUSE_CHANGE_FONT:
                    sizeFont(&rect,1);
                    client->paint();
                    break;
                case TERM_MOUSE_CHANGE_DIMENSION:
                    if( sizepop )
                        sizepop->show( FALSE );
                    client->endSizing();
                    break;
                case TERM_MOUSE_NO_EFFECT:
                    client->setDimensions(TRUE);
                    client->endSizing();
                    break;
                }
                tt_linespacing[vmode] = newLineSpacing;
            }
            break;
        case SIZE_MINIMIZED:
            break;
        case SIZE_MAXIMIZED:
            if ( wmSize == SIZE_RESTORED ) {
                RECT rect;
                rect.top = 0;
                rect.left = 0;
                rect.bottom = HIWORD(lParam);
                rect.right = LOWORD(lParam);
                kglob->saveMouseEffect = kglob->mouseEffect;
                kglob->saveLineSpacing = tt_linespacing[vmode];
                switch (kglob->mouseEffect) {
                case TERM_MOUSE_CHANGE_FONT:
                    sizeFont(&rect,0);
                    client->paint();
                    break;
                case TERM_MOUSE_CHANGE_DIMENSION:
                    if( sizepop )
                        sizepop->show( FALSE );
                    client->endSizing();
                    break;
                case TERM_MOUSE_NO_EFFECT:
                    client->endSizing();
                    break;
                }
            }
            break;  
        case SIZE_MAXSHOW:
        case SIZE_MAXHIDE:
        default:
            break;
        }

        wmSize = (UINT)wParam;
        break;

    case WM_USER_EXITSIZEMOVE:
#ifdef WM_EXITSIZEMOVE
    case WM_EXITSIZEMOVE:
#endif
    {
        //printf("KAppWin WM_EXITSIZEMOVE\n");
        //debug(F111,"KAppWin::message","WM_EXITSIZEMOVE",msg);
        BYTE keyState[256];
        int  save = kglob->mouseEffect;
        if (GetKeyboardState(keyState)) {
            if ( (keyState[VK_CONTROL] & 128) && 
                !(keyState[VK_SHIFT] & 128) && 
                !(keyState[VK_MENU] & 128))
                kglob->mouseEffect = TERM_MOUSE_CHANGE_FONT;
            else if ( !(keyState[VK_CONTROL] & 128) && 
                      (keyState[VK_SHIFT] & 128) && 
                      !(keyState[VK_MENU] & 128))
                kglob->mouseEffect = TERM_MOUSE_CHANGE_DIMENSION;
        //    else 
        //        kglob->mouseEffect = TERM_MOUSE_NO_EFFECT;
        }
        if( sizepop )
            sizepop->show( FALSE );
        client->endSizing();
        kglob->mouseEffect = save;
        break;
    }

    case WM_GETMINMAXINFO:
        //printf("KAppWin WM_GETMINMAXINFO\n");
        //debug(F111,"KAppWin::message","WM_GETMINMAXINFO",msg);
        // use of this code prevents Maximize from changing the 
        // window dimensions.
        if ( kglob->mouseEffect == TERM_MOUSE_NO_EFFECT )
        {
            int maxw = 0, maxh = 0;
            if( !client->getMaxpDim( maxw, maxh ) )
                break;

            LPMINMAXINFO info = (LPMINMAXINFO)lParam;
            info->ptMaxSize.x = maxw;
            info->ptMaxSize.y = maxh;
            info->ptMaxPosition.x = 0;
            info->ptMaxPosition.y = 0;
        }
        break;

    case WM_DRAWITEM:
        //debug(F111,"KAppWin::message","WM_DRAWITEM",msg);
        done = status->message( hwnd, msg, wParam, lParam );
        break;

    case WM_INITMENU:
        //debug(F111,"KAppWin::message","WM_INITMENU",msg);
        initMenu();
        break;

    case WM_SYSCOMMAND:
    case WM_COMMAND:
        //debug(F111,"KAppWin::message","WM_COMMAND",msg);
        {
            //debug(F111,"KAppWin::message WM_COMMAND","LOWORD(wParam)",LOWORD(wParam));
            switch( LOWORD(wParam) )
            {
            case ID_OPTIONS_FONT:
                {
                    //debug(F111,"KAppWin::message WM_COMMAND","ID_OPTIONS_FONT",LOWORD(wParam));
                    LOGFONT logfont;
                    PLOGFONT curfont = client->getFont()->getLogFont();
                    memcpy( &logfont, curfont, sizeof(LOGFONT) );
                    
                    KFontDialog fontdlg( kglob, this );
                    fontdlg.show( &logfont );

                    if( memcmp( &logfont, curfont, sizeof(LOGFONT) ) != 0 ) {
                        KFont* newFont = new KFont( &logfont );
                        setKFont( newFont );
                    }
                    break;
                }
            case ID_OPTIONS_CUSTOMIZESTATUSBAR:
                {
                    //debug(F111,"KAppWin::message WM_COMMAND","ID_OPTIONS_CUSTOMIZESTATUSBAR",LOWORD(wParam));
                    //Bool stat = menu->toggleCheck( 
                    //    ID_OPTIONS_CUSTOMIZESTATUSBAR );
                    status->customize();
                    break;
                }
            case ID_HELP_ABOUT:
                {
                    //debug(F111,"KAppWin::message WM_COMMAND","ID_HELP_ABOUT",LOWORD(wParam));
                    KAbout about( kglob, this );
                    about.show();
                    break;
                }
            case ID_HELP_HELPONKERMIT:
                {
#ifndef NOHELP
                    //debug(F111,"KAppWin::message WM_COMMAND","ID_HELP_HELPONKERMIT",LOWORD(wParam));
                    char tmp[256];
                    char* c = ::getVar( LOG_HOME_DIR );
                    strcpy( tmp, c );
                    strcat( tmp, "kermit95.hlp" );
                    WinHelp( hWnd, tmp, HELP_INDEX, 0 );
#endif /* NOHELP */
                    break;
                }

//            case ID_WINDOW_TERMINAL:
//                debug(F111,"KAppWin::message WM_COMMAND","ID_WINDOW_TERMINAL",LOWORD(wParam));
//                PostMessage( hWnd, WM_GOTO_TERMINAL_WINDOW, 0, 0 );
//                break;
//            case ID_WINDOW_COMMAND:
//                debug(F111,"KAppWin::message WM_COMMAND","ID_WINDOW_COMMAND",LOWORD(wParam));
//                PostMessage( hWnd, WM_GOTO_COMMAND_WINDOW, 0, 0 );
//                break;
            case ID_WINDOW_CLIPBOARD:
                //debug(F111,"KAppWin::message WM_COMMAND","ID_WINDOW_CLIPBOARD",LOWORD(wParam));
                ShellExecute( hWnd, "open", "clipbrd.exe", NULL, NULL, SW_SHOW );
                break;
            case ID_WINDOW_TEXTEDIT:
                //debug(F111,"KAppWin::message WM_COMMAND","ID_WINDOW_TEXTEDIT",LOWORD(wParam));
                ShellExecute( hWnd, "open", "notepad.exe", NULL, NULL, SW_SHOW );
                break;
            }
            break;
        }
    }

    if (msg == WM_SYSCOMMAND) {
        // For WM_SYSCOMMAND, a return value of 0 indicates the message was
        // processed.
        if (done) return 0;
        return 1;
    }

    return done;
}
