/******************************************************************************
*
*
* Notepad2
*
* Notepad2.c
*   Main application window functionality
*
* See Readme.txt for more information about this source code.
* Please send me your comments to this work.
*
* Distributed under the terms of the GNU General Public License,
* see License.txt for details.
*
*                                              (c) Florian Balmer 1996-2004
*                                                       textview@bluewin.ch
*                                               http://www.flos-freeware.ch
*
*
******************************************************************************/
#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <richedit.h>
#include <shellapi.h>
#include <commdlg.h>
#include <stdio.h>
#include <string.h>
#include "scintilla.h"
#include "scilexer.h"
#include "edit.h"
#include "styles.h"
#include "helpers.h"
#include "dialogs.h"
#include "appreg.h"
#include "notepad2.h"
#include "resource.h"



/******************************************************************************
*
* Local and global Variables for Notepad2.c
*
*/
HWND      hwndStatus;
HWND      hwndToolbar;
HWND      hwndReBar;
HWND      hwndEdit;
HWND      hwndEditFrame;
HWND      hwndMain;
HWND      hwndFindReplace = NULL;
HWND      hwndNextCBChain = NULL;

#define NUMTOOLBITMAPS  26
#define NUMINITIALTOOLS 24

TBBUTTON  tbbMainWnd[] = { {0,IDT_FILE_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {1,IDT_FILE_OPEN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {2,IDT_FILE_METAPATH,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {3,IDT_FILE_SAVE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {0,0,0,TBSTYLE_SEP,0,0},
                           {4,IDT_EDIT_UNDO,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {5,IDT_EDIT_REDO,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {0,0,0,TBSTYLE_SEP,0,0},
                           {6,IDT_EDIT_CUT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {7,IDT_EDIT_COPY,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {8,IDT_EDIT_PASTE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {0,0,0,TBSTYLE_SEP,0,0},
                           {9,IDT_EDIT_FIND,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {10,IDT_EDIT_REPLACE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {0,0,0,TBSTYLE_SEP,0,0},
                           {11,IDT_VIEW_WORDWRAP,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {0,0,0,TBSTYLE_SEP,0,0},
                           {12,IDT_VIEW_ZOOMIN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {13,IDT_VIEW_ZOOMOUT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {0,0,0,TBSTYLE_SEP,0,0},
                           {14,IDT_VIEW_SCHEME,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {15,IDT_VIEW_SCHEMECONFIG,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {0,0,0,TBSTYLE_SEP,0,0},
                           {16,IDT_FILE_EXIT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {17,IDT_FILE_SAVEAS,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {18,IDT_FILE_SAVECOPY,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {19,IDT_EDIT_COPYALL,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {20,IDT_EDIT_CLEAR,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {21,IDT_EDIT_FINDNEXT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {22,IDT_EDIT_FINDPREV,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {23,IDT_FILE_PRINT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {24,IDT_FILE_OPENFAV,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0},
                           {25,IDT_FILE_ADDTOFAV,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0} };

BOOL      bSaveSettings;
BOOL      bSaveRecentFiles;
BOOL      bSaveFindReplace;
char      tchOpenWithDir[MAX_PATH];
char      tchFavoritesDir[MAX_PATH];
char      tchDefaultExtension[64];
char      tchToolbarBitmap[MAX_PATH];
char      tchToolbarBitmapHot[MAX_PATH];
char      tchToolbarBitmapDisabled[MAX_PATH];
BOOL      bShortPathNames;
BOOL      fWordWrap;
int       iWordWrapIndent;
int       iWordWrapSymbols;
BOOL      bShowWordWrapSymbols;
BOOL      bMatchBraces;
BOOL      bAutoIndent;
BOOL      bAutoCloseTags;
BOOL      bShowIndentGuides;
BOOL      bTabsAsSpaces;
int       iTabWidth;
BOOL      bMarkLongLines;
int       iLongLinesLimit;
int       iLongLineMode;
BOOL      bShowSelectionMargin;
BOOL      bShowLineNumbers;
BOOL      bViewWhiteSpace;
BOOL      bViewEOLs;
int       iDefaultEncoding;
int       iDefaultEOLMode;
int       iPrintHeader;
int       iPrintFooter;
int       iPrintZoom;
RECT      pagesetupMargin;
BOOL      bSaveBeforeRunningTools;
//BOOL      bEnableFileWatching;
int       iEscFunction;
BOOL      bAlwaysOnTop;
BOOL      bMinimizeToTray;
BOOL      bTransparentMode;
BOOL      bTransparentModeAvailable;
BOOL      bShowToolbar;
BOOL      bShowStatusbar;

typedef struct _wi
{
  int x;
  int y;
  int cx;
  int cy;
  int max;
} WININFO;

WININFO wi;
int     cyReBar;
int     cyReBarFrame;
int     cxEditFrame;
int     cyEditFrame;

int     cxFileMRUDlg;
int     cyFileMRUDlg;
int     cxOpenWithDlg;
int     cyOpenWithDlg;
int     cxFavoritesDlg;
int     cyFavoritesDlg;

LPSTR     lpFileArg = NULL;
HANDLE    hFileMRU;

char      szCurFile[MAX_PATH+40];
BOOL      bModified;
BOOL      bReadOnly = FALSE;
int       iCodePage;
int       iInitialCP;
int       iEOLMode;

int       iDefaultCodePage;
int       iDefaultCharSet;
BOOL      bAutoSelACP;

int       iInitialLine;
int       iInitialColumn;

BOOL      bLastCopyFromMe = FALSE;
UINT      uidsAppTitle = IDS_APPTITLE;

//HANDLE    hChangeHandle = NULL;
//BOOL      bRunningWatch = FALSE;
//BOOL      bPendingChangeNotify = FALSE;
//WIN32_FIND_DATA fdCurFile;

EDITFINDREPLACE efrData = { "", "", "", "", 0, 0, 0, 0, NULL };
UINT cpLastFind = 0;

int iEncodings[5] = { NCP_DEFAULT,
                      NCP_UNICODE|NCP_UNICODE_BOM,
                      NCP_UNICODE|NCP_UNICODE_REVERSE|NCP_UNICODE_BOM,
                      NCP_UTF8,
                      NCP_UTF8|NCP_UTF8_SIGN };

int iLineEndings[3] = { SC_EOL_CRLF,SC_EOL_LF, SC_EOL_CR };

struct {
  int flags;
  int location;
} WrapSymbols[4] = { { 1, 1 },
                     { 2, 2 },
                     { 3, 3 },
                     { 3, 0 } };

LPMALLOC  g_lpMalloc;
HINSTANCE g_hInstance;


extern int Scintilla_RegisterClasses(HINSTANCE);
extern int Scintilla_ReleaseResources();



//=============================================================================
//
// Flags
//
int flagNoReuseWindow     = 0;
int flagStartAsTrayIcon   = 0;
int flagUnregProgram      = 0;
int flagNoFadeHidden      = 0;
int flagPosParam          = 0;
int flagNewFromClipboard  = 0;
int flagPasteBoard        = 0;
int flagJumpTo            = 0;
int flagDisplayHelp       = 0;



//=============================================================================
//
//  WinMain()
//
//
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,
                   LPSTR lpCmdLine,int nCmdShow)
{

  MSG msg;
  HWND hwnd;
  HACCEL hAccel;
  INITCOMMONCONTROLSEX icex;
  //HMODULE hSciLexer;

  // Set global variable g_hInstance
  g_hInstance = hInstance;

  // Get Flags and FileArg
  ParseCommandLine(lpCmdLine);

  // Command Line Help Dialog
  if (flagDisplayHelp)
  {
    DisplayCmdLineHelp();
    return(0);
  }

  // Unregister Dialog
  if (flagUnregProgram)
  {
    UnregisterApp(hInstance);
    return(0);
  }

  // Try to activate another window
  if (ActivatePrevInst())
    return(0);

  // Init OLE and Common Controls
  OleInitialize(NULL);
  SHGetMalloc(&g_lpMalloc);

  icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  icex.dwICC  = ICC_WIN95_CLASSES|ICC_COOL_CLASSES|ICC_BAR_CLASSES|ICC_USEREX_CLASSES;
  InitCommonControlsEx(&icex);

  // Load SciLexer.dll
  //SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
  //hSciLexer = LoadLibrary("SciLexer");
  //if (!hSciLexer) {
  //  MsgBox(MBWARN,IDS_ERR_NOSCILEXER);
  //  return(0); }

  // Error mode set to SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX
  // from here throughout the whole program
  SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);

  Scintilla_RegisterClasses(hInstance);

  // Load Settings
  LoadSettings();

  if (!InitApplication(hInstance))
    return FALSE;

  if (!(hwnd = InitInstance(hInstance,lpCmdLine,nCmdShow)))
    return FALSE;

  hAccel = LoadAccelerators(hInstance,MAKEINTRESOURCE(IDR_MAINWND));

  while (GetMessage(&msg,NULL,0,0))
  {
    if (!TranslateAccelerator(hwnd,hAccel,&msg))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }

  // Save Settings is done elsewhere

  Scintilla_ReleaseResources();
  //FreeLibrary(hSciLexer);
  g_lpMalloc->lpVtbl->Release(g_lpMalloc);
  OleUninitialize();

  return(msg.wParam);

  hPrevInst;

}


//=============================================================================
//
//  InitApplication()
//
//
BOOL InitApplication(HINSTANCE hInstance)
{

  WNDCLASS   wc;

  wc.style         = CS_BYTEALIGNWINDOW | CS_DBLCLKS;
  wc.lpfnWndProc   = (WNDPROC)MainWndProc;
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = 0;
  wc.hInstance     = hInstance;
  wc.hIcon         = LoadIcon(hInstance,MAKEINTRESOURCE(IDR_MAINWND));
  wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAINWND);
  wc.lpszClassName = (!flagPasteBoard) ? WC_NOTEPAD2 : WC_NOTEPAD2PASTEBOARD;

  return RegisterClass(&wc);

}


//=============================================================================
//
//  InitInstance()
//
//
HWND InitInstance(HINSTANCE hInstance,LPSTR pszCmdLine,int nCmdShow)
{

  RECT rcWorkArea;

  // Transform window rect from workarea to screen
  SystemParametersInfo(SPI_GETWORKAREA,0,&rcWorkArea,0);
  if (wi.x != CW_USEDEFAULT) wi.x += rcWorkArea.left;
  if (wi.y != CW_USEDEFAULT) wi.y += rcWorkArea.top;

  hwndMain = CreateWindowEx(
               0,
               (!flagPasteBoard) ? WC_NOTEPAD2 : WC_NOTEPAD2PASTEBOARD,
               "Notepad2",
               WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
               wi.x,
               wi.y,
               wi.cx,
               wi.cy,
               NULL,
               NULL,
               hInstance,
               NULL);

  if (wi.max)
    nCmdShow = SW_SHOWMAXIMIZED;

  if (bAlwaysOnTop)
    SetWindowPos(hwndMain,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

  if (bTransparentMode)
    SetWindowTransparentMode(hwndMain,TRUE);

  // Current file information -- moved in front of ShowWindow()
  FileLoad(TRUE,TRUE,FALSE,FALSE,"");

  if (!flagStartAsTrayIcon) {
    ShowWindow(hwndMain,nCmdShow);
    UpdateWindow(hwndMain); }
  else {
    ShowWindow(hwndMain,SW_HIDE);    // trick ShowWindow()
    ShowNotifyIcon(hwndMain,TRUE); }

  // Pathname parameter
  if (lpFileArg /*&& !flagNewFromClipboard*/)
  {
    // Open from Directory
    if (PathIsDirectory(lpFileArg))
    {
      char tchFile[MAX_PATH];
      if (OpenFileDlg(hwndMain,tchFile,COUNTOF(tchFile),lpFileArg))
        FileLoad(FALSE,FALSE,FALSE,FALSE,tchFile);
    } else {
      if (FileLoad(FALSE,FALSE,FALSE,FALSE,lpFileArg)) {
        if (flagJumpTo) // Jump to position
          EditJumpTo(hwndEdit,iInitialLine,iInitialColumn); } }
    GlobalFree(lpFileArg);
  }

  // Check for /c [if no file is specified] -- even if a file is specified
  /*else */if (flagNewFromClipboard) {
    if (SendMessage(hwndEdit,SCI_CANPASTE,0,0)) {
      BOOL bAutoIndent2 = bAutoIndent;
      bAutoIndent = 0;
      EditJumpTo(hwndEdit,-1,0);
      if (SendMessage(hwndEdit,SCI_GETLENGTH,0,0) > 0)
        SendMessage(hwndEdit,SCI_NEWLINE,0,0);
      SendMessage(hwndEdit,SCI_PASTE,0,0);
      SendMessage(hwndEdit,SCI_NEWLINE,0,0);
      bAutoIndent = bAutoIndent2; } }

  // Check for Paste Board option -- after loading files
  if (flagPasteBoard) {
    bLastCopyFromMe = TRUE;
    hwndNextCBChain = SetClipboardViewer(hwndMain);
    uidsAppTitle = IDS_APPTITLE_PASTEBOARD;
    SetWindowTitle(hwndMain,uidsAppTitle,IDS_UNTITLED,szCurFile,
      bShortPathNames,bModified || iCodePage != iInitialCP,
      IDS_READONLY,bReadOnly);
    bLastCopyFromMe = FALSE;
  }

  // If start as tray icon, set current filename as tooltip
  if (flagStartAsTrayIcon)
    SetNotifyIconTitle(hwndMain);

  // Toolbar
  UpdateToolbar();

  // Statusbar
  UpdateStatusbar();

  return(hwndMain);

}


//=============================================================================
//
//  MainWndProc()
//
//  Messages are distributed to the MsgXXX-handlers
//
//
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam)
{
  static BOOL bHideIcon = FALSE;

  switch(umsg)
  {

    // Quickly handle painting and sizing messages, found in ScintillaWin.cxx
    // Cool idea, don't know if this has any effect... ;-)
    case WM_MOVE:
    case WM_MOUSEACTIVATE:
    case WM_NCHITTEST:
    case WM_NCCALCSIZE:
    case WM_NCPAINT:
    case WM_PAINT:
    case WM_ERASEBKGND:
    case WM_NCMOUSEMOVE:
    case WM_NCLBUTTONDOWN:
    case WM_WINDOWPOSCHANGING:
    case WM_WINDOWPOSCHANGED:
      return DefWindowProc(hwnd,umsg,wParam,lParam);

    case WM_CREATE:
      return MsgCreate(hwnd,wParam,lParam);


    case WM_DESTROY:
      {
        WINDOWPLACEMENT wndpl;

        // Terminate file watching
        //InstallFileWatching(NULL);

        // GetWindowPlacement
        wndpl.length = sizeof(WINDOWPLACEMENT);
        GetWindowPlacement(hwnd,&wndpl);

        wi.x = wndpl.rcNormalPosition.left;
        wi.y = wndpl.rcNormalPosition.top;
        wi.cx = wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left;
        wi.cy = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top;
        wi.max = (IsZoomed(hwnd) || (wndpl.flags & WPF_RESTORETOMAXIMIZED));

        DragAcceptFiles(hwnd,FALSE);

        // Restore clipboard chain...
        if (flagPasteBoard)
          ChangeClipboardChain(hwnd,hwndNextCBChain);

        // Cleanup unwanted MRU's
        FreeMRUList(hFileMRU);
        if (!bSaveRecentFiles)
        {
          BOOL bError;
          RegDeleteKeyEx(HKEY_CURRENT_USER,"Software\\Notepad2\\Recent Files",&bError);
        }

        if (!bSaveFindReplace)
        {
          BOOL bError;
          RegDeleteKeyEx(HKEY_CURRENT_USER,"Software\\Notepad2\\Recent Find",&bError);
          RegDeleteKeyEx(HKEY_CURRENT_USER,"Software\\Notepad2\\Recent Replace",&bError);
        }

        // call SaveSettings() when hwndToolbar is still valid
        SaveSettings(FALSE);

        // Remove tray icon if necessary
        ShowNotifyIcon(hwnd,FALSE);

        PostQuitMessage(0);
      }
      break;


    case WM_CLOSE:
      if (FileSave(FALSE,TRUE,FALSE,FALSE))
        DestroyWindow(hwnd);
      break;


    case WM_QUERYENDSESSION:
      if (FileSave(FALSE,TRUE,FALSE,FALSE))
        return TRUE;
      else
        return FALSE;


    // Reinitialize theme-dependent values and resize windows
    case 0x031A /*WM_THEMECHANGED*/:
      MsgThemeChanged(hwnd,wParam,lParam);
      break;


    // update Scintilla colors
    case WM_SYSCOLORCHANGE:
      {
        extern PEDITLEXER pLexCurrent;
        Style_SetLexer(hwndEdit,pLexCurrent);
        return DefWindowProc(hwnd,umsg,wParam,lParam);
      }


    //case WM_TIMER:
    //  break;


    case WM_SIZE:
      MsgSize(hwnd,wParam,lParam);
      break;


    case WM_SETFOCUS:
      SetFocus(hwndEdit);

      //if (bPendingChangeNotify)
      //  PostMessage(hwnd,WM_CHANGENOTIFY,0,0);
      break;


    case WM_DROPFILES:
      {
        char szBuf[MAX_PATH+40];
        HDROP hDrop = (HDROP)wParam;

        // Reset Change Notify
        //bPendingChangeNotify = FALSE;

        if (IsIconic(hwnd))
          ShowWindow(hwnd,SW_RESTORE);

        //SetForegroundWindow(hwnd);

        DragQueryFile(hDrop,0,szBuf,COUNTOF(szBuf));
        FileLoad(FALSE,FALSE,FALSE,FALSE,szBuf);

        if (DragQueryFile(hDrop,(UINT)(-1),NULL,0) > 1)
          MsgBox(MBINFO,IDS_ERR_DROP);

        DragFinish(hDrop);
      }
      break;


    case WM_COPYDATA:
      {
        PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;

        // Reset Change Notify
        //bPendingChangeNotify = FALSE;

        if (pcds->dwData == DATA_NOTEPAD2_FILEARG)
        {
          LPSTR lpsz = LocalAlloc(LPTR,pcds->cbData);
          CopyMemory(lpsz,pcds->lpData,pcds->cbData);
          FileLoad(FALSE,FALSE,FALSE,FALSE,lpsz);
          LocalFree(lpsz);
        }
      }
      return TRUE;


    case WM_CONTEXTMENU:
    {
      HMENU hmenu;
      int imenu = 0;
      POINT pt;
      int nID = GetDlgCtrlID((HWND)wParam);

      if ((nID != IDC_EDIT) && (nID != IDC_STATUSBAR) &&
          (nID != IDC_REBAR) && (nID != IDC_TOOLBAR))
        return DefWindowProc(hwnd,umsg,wParam,lParam);

      hmenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_POPUPMENU));
      //SetMenuDefaultItem(GetSubMenu(hmenu,1),0,FALSE);

      pt.x = (int)(short)LOWORD(lParam);
      pt.y = (int)(short)HIWORD(lParam);

      switch(nID)
      {
        case IDC_EDIT:
          {
            int iSelStart = SendMessage(hwndEdit,SCI_GETSELECTIONSTART,0,0);
            int iSelEnd   = SendMessage(hwndEdit,SCI_GETSELECTIONEND,0,0);

            if (iSelStart == iSelEnd && pt.x != -1 && pt.y != -1)
            {
              int iNewPos;
              POINT ptc = { pt.x, pt.y };
              ScreenToClient(hwndEdit,&ptc);
              iNewPos = SendMessage(hwndEdit,SCI_POSITIONFROMPOINT,(WPARAM)ptc.x,(LPARAM)ptc.y);
              SendMessage(hwndEdit,SCI_GOTOPOS,(WPARAM)iNewPos,0);
            }

            if (pt.x == -1 && pt.y == -1)
            {
              int iCurrentPos = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
              pt.x = SendMessage(hwndEdit,SCI_POINTXFROMPOSITION,0,(LPARAM)iCurrentPos);
              pt.y = SendMessage(hwndEdit,SCI_POINTYFROMPOSITION,0,(LPARAM)iCurrentPos);
              ClientToScreen(hwndEdit,&pt);
            }
            imenu = 0;
          }
          break;

        case IDC_TOOLBAR:
        case IDC_STATUSBAR:
        case IDC_REBAR:
          if (pt.x == -1 && pt.y == -1)
            GetCursorPos(&pt);
          imenu = 1;
          break;
      }

      TrackPopupMenuEx(GetSubMenu(hmenu,imenu),
        TPM_LEFTBUTTON | TPM_RIGHTBUTTON,pt.x,pt.y,hwnd,NULL);

      DestroyMenu(hmenu);
    }
    break;


    case WM_INITMENU:
      MsgInitMenu(hwnd,wParam,lParam);
      break;


    case WM_NOTIFY:
      return MsgNotify(hwnd,wParam,lParam);


    case WM_COMMAND:
      return MsgCommand(hwnd,wParam,lParam);


    case WM_SYSCOMMAND:
      switch (wParam)
      {
        case SC_MINIMIZE:
          ShowOwnedPopups(hwnd,FALSE);
          if (bMinimizeToTray) {
            MinimizeWndToTray(hwnd);
            ShowNotifyIcon(hwnd,TRUE);
            SetNotifyIconTitle(hwnd);
            return(0); }
          else
            return DefWindowProc(hwnd,umsg,wParam,lParam);

        case SC_RESTORE: {
          LRESULT lrv = DefWindowProc(hwnd,umsg,wParam,lParam);
          ShowOwnedPopups(hwnd,TRUE);
          return(lrv); }
      }
      return DefWindowProc(hwnd,umsg,wParam,lParam);


    //case WM_CHANGENOTIFY:
    //  {
    //    if (bPendingChangeNotify && (GetForegroundWindow() == hwnd || GetActiveWindow() == hwnd))
    //    {
    //      bPendingChangeNotify = FALSE;
    //      if (MsgBox(MBYESNO,IDS_ASK_ENCODING) == IDYES)
    //      {
    //        FileLoad(TRUE,FALSE,TRUE,FALSE,szCurFile);
    //      }
    //      InstallFileWatching(szCurFile);
    //    }
    //  }
    //  break;


    //// This message is posted before Notepad2 reactivates itself
    //case WM_CHANGENOTIFYCLEAR:
    //  bPendingChangeNotify = FALSE;
    //  break;


    case WM_DRAWCLIPBOARD:
      if (!bLastCopyFromMe) {
        if (SendMessage(hwndEdit,SCI_CANPASTE,0,0)) {
          BOOL bAutoIndent2 = bAutoIndent;
          bAutoIndent = 0;
          EditJumpTo(hwndEdit,-1,0);
          if (SendMessage(hwndEdit,SCI_GETLENGTH,0,0) > 0)
            SendMessage(hwndEdit,SCI_NEWLINE,0,0);
          SendMessage(hwndEdit,SCI_PASTE,0,0);
          SendMessage(hwndEdit,SCI_NEWLINE,0,0);
          bAutoIndent = bAutoIndent2; }
        }
      else
        bLastCopyFromMe = FALSE;
      if (hwndNextCBChain)
        SendMessage(hwndNextCBChain,WM_DRAWCLIPBOARD,wParam,lParam);
      break;


    case WM_CHANGECBCHAIN:
      if ((HWND)wParam == hwndNextCBChain)
        hwndNextCBChain = (HWND)lParam;
      if (hwndNextCBChain)
        SendMessage(hwndNextCBChain,WM_CHANGECBCHAIN,lParam,wParam);
      break;


    case WM_TRAYMESSAGE:
      switch(lParam)
      {
        case WM_RBUTTONUP: {

          HMENU hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_POPUPMENU));
          HMENU hMenuPopup = GetSubMenu(hMenu,2);

          POINT pt;
          int iCmd;

          SetForegroundWindow(hwnd);

          GetCursorPos(&pt);
          SetMenuDefaultItem(hMenuPopup,IDM_TRAY_RESTORE,FALSE);
          iCmd = TrackPopupMenu(hMenuPopup,
                   TPM_NONOTIFY|TPM_RETURNCMD|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
                   pt.x,pt.y,0,hwnd,NULL);

          PostMessage(hwnd,WM_NULL,0,0);

          DestroyMenu(hMenu);

          if (iCmd == IDM_TRAY_RESTORE) {
            RestoreWndFromTray(hwnd);
            ShowOwnedPopups(hwnd,TRUE);
            ShowNotifyIcon(hwnd,FALSE);
            bHideIcon = FALSE; }

          else if (iCmd == IDM_TRAY_EXIT) {
              //ShowNotifyIcon(hwnd,FALSE);
              SendMessage(hwnd,WM_CLOSE,0,0); } }

          return TRUE;

        case WM_LBUTTONDBLCLK:
          RestoreWndFromTray(hwnd);
          ShowOwnedPopups(hwnd,TRUE);
          bHideIcon = TRUE;
          return TRUE;

        case WM_LBUTTONUP:
          if(bHideIcon) {
            ShowNotifyIcon(hwnd,FALSE);
            bHideIcon = FALSE; }
            return TRUE;
      }
      break;


    default:
      return DefWindowProc(hwnd,umsg,wParam,lParam);

  }

  return(0);

}


//=============================================================================
//
//  MsgCreate() - Handles WM_CREATE
//
//
LRESULT MsgCreate(HWND hwnd,WPARAM wParam,LPARAM lParam)
{

  RECT rc;
  RECT rc2;

  TBSAVEPARAMS tbsp = { HKEY_CURRENT_USER, "Software\\Notepad2\\Toolbar", "Settings" };
  CREATEMRULIST cl = { sizeof(CREATEMRULIST), 16, 2, HKEY_CURRENT_USER,
                       "Software\\Notepad2\\Recent Files", NULL };

  HINSTANCE hInstance = ((LPCREATESTRUCT)lParam)->hInstance;

  // Setup edit control
  hwndEdit = EditCreate(hwnd);

  // Word wrap
  SendMessage(hwndEdit,SCI_SETWRAPMODE,(fWordWrap)?SC_WRAP_WORD:SC_WRAP_NONE,0);
  SendMessage(hwndEdit,SCI_SETWRAPSTARTINDENT,iWordWrapIndent,0);
  if (bShowWordWrapSymbols) {
    SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGSLOCATION,WrapSymbols[iWordWrapSymbols].location,0);
    SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGS,WrapSymbols[iWordWrapSymbols].flags,0); }
  else {
    SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGS,0,0); }

  // Indent Guides
  SendMessage(hwndEdit,SCI_SETINDENTATIONGUIDES,bShowIndentGuides,0);

  // Tabs
  SendMessage(hwndEdit,SCI_SETUSETABS,!bTabsAsSpaces,0);
  SendMessage(hwndEdit,SCI_SETTABWIDTH,iTabWidth,0);
  SendMessage(hwndEdit,SCI_SETINDENT,0,0);

  // Long Lines
  if (bMarkLongLines)
    SendMessage(hwndEdit,SCI_SETEDGEMODE,(iLongLineMode == EDGE_LINE)?EDGE_LINE:EDGE_BACKGROUND,0);
  else
    SendMessage(hwndEdit,SCI_SETEDGEMODE,EDGE_NONE,0);
  SendMessage(hwndEdit,SCI_SETEDGECOLUMN,iLongLinesLimit,0);

  // Margins
  SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,2,0);
  SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,1,(bShowSelectionMargin)?16:0);
  UpdateLineNumberWidth();
  //SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,0,
  //  (bShowLineNumbers)?SendMessage(hwndEdit,SCI_TEXTWIDTH,STYLE_LINENUMBER,(LPARAM)"_999999_"):0);

  // Nonprinting characters
  SendMessage(hwndEdit,SCI_SETVIEWWS,(bViewWhiteSpace)?SCWS_VISIBLEALWAYS:SCWS_INVISIBLE,0);
  SendMessage(hwndEdit,SCI_SETVIEWEOL,bViewEOLs,0);

  hwndEditFrame = CreateWindowEx(
                    WS_EX_CLIENTEDGE,
                    WC_LISTVIEW,
                    NULL,
                    WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
                    0,0,100,100,
                    hwnd,
                    (HMENU)IDC_EDITFRAME,
                    hInstance,
                    NULL);

  if (PrivateIsAppThemed()) {

    SetWindowLong(hwndEdit,GWL_EXSTYLE,GetWindowLong(hwndEdit,GWL_EXSTYLE) & ~WS_EX_CLIENTEDGE);
    SetWindowPos(hwndEdit,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);

    GetClientRect(hwndEditFrame,&rc);
    GetWindowRect(hwndEditFrame,&rc2);

    cxEditFrame = ((rc2.right-rc2.left) - (rc.right-rc.left)) / 2;
    cyEditFrame = ((rc2.bottom-rc2.top) - (rc.bottom-rc.top)) / 2; }

  else {

    cxEditFrame = 0;
    cyEditFrame = 0; }

  // Create Toolbar and Statusbar
  CreateBars(hwnd,hInstance,&tbsp);

  // Window Initialization

  // Menu
  //SetMenuDefaultItem(GetSubMenu(GetMenu(hwnd),0),0);

  // Drag & Drop
  DragAcceptFiles(hwnd,TRUE);

  // File MRU
  hFileMRU = CreateMRUList(&cl);

  return(0);

}


//=============================================================================
//
//  CreateBars() - Create Toolbar and Statusbar
//
//
void CreateBars(HWND hwnd,HINSTANCE hInstance,LPTBSAVEPARAMS lptbsp)
{
  RECT rc;

  REBARINFO rbi;
  REBARBANDINFO rbBand;

  BITMAP bmp;
  HBITMAP hbmp;
  HIMAGELIST himl;
  char szTmp[MAX_PATH];
  COLORMAP tbColorMap = { RGB(192,192,192), RGB(212,208,200) };

  DWORD dwToolbarStyle = WS_TOOLBAR;
  DWORD dwStatusbarStyle = WS_CHILD | WS_CLIPSIBLINGS;
  DWORD dwReBarStyle = WS_REBAR;

  BOOL bIsAppThemed = PrivateIsAppThemed();

  HKEY hKey;
  int i;
  char tchDesc[256];
  char tchIndex[256];

  if (bShowToolbar)
    dwReBarStyle |= WS_VISIBLE;

  hwndToolbar = CreateWindowEx(0,TOOLBARCLASSNAME,NULL,dwToolbarStyle,
                               0,0,0,0,hwnd,(HMENU)IDC_TOOLBAR,hInstance,NULL);

  SendMessage(hwndToolbar,TB_BUTTONSTRUCTSIZE,(WPARAM)sizeof(TBBUTTON),0);

  // Add normal Toolbar Bitmap
  hbmp = NULL;
  if (lstrlen(tchToolbarBitmap))
  {
    if (!SearchPath(NULL,tchToolbarBitmap,NULL,COUNTOF(szTmp),szTmp,NULL))
      lstrcpy(szTmp,tchToolbarBitmap);
    hbmp = LoadImage(NULL,szTmp,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
  }
  if (!hbmp)
    //hbmp = CreateMappedBitmap(hInstance,(IDR_MAINWND),0,&tbColorMap,1);
    hbmp = LoadBitmap(hInstance,MAKEINTRESOURCE(IDR_MAINWND));
  GetObject(hbmp,sizeof(BITMAP),&bmp);
  himl = ImageList_Create(bmp.bmWidth/NUMTOOLBITMAPS,bmp.bmHeight,ILC_COLORDDB|ILC_MASK,0,0);
  ImageList_AddMasked(himl,hbmp,RGB(255,0,255));
  DeleteObject(hbmp);
  SendMessage(hwndToolbar,TB_SETIMAGELIST,0,(LPARAM)himl);

  // Optionally add hot Toolbar Bitmap
  hbmp = NULL;
  if (lstrlen(tchToolbarBitmapHot))
  {
    if (!SearchPath(NULL,tchToolbarBitmapHot,NULL,COUNTOF(szTmp),szTmp,NULL))
      lstrcpy(szTmp,tchToolbarBitmapHot);
    if (hbmp = LoadImage(NULL,szTmp,IMAGE_BITMAP,0,0,LR_LOADFROMFILE))
    {
      GetObject(hbmp,sizeof(BITMAP),&bmp);
      himl = ImageList_Create(bmp.bmWidth/NUMTOOLBITMAPS,bmp.bmHeight,ILC_COLORDDB|ILC_MASK,0,0);
      ImageList_AddMasked(himl,hbmp,RGB(255,0,255));
      DeleteObject(hbmp);
      SendMessage(hwndToolbar,TB_SETHOTIMAGELIST,0,(LPARAM)himl);
    }
  }

  // Add disabled Toolbar Bitmap
  hbmp = NULL;
  if (lstrlen(tchToolbarBitmapDisabled))
  {
    if (!SearchPath(NULL,tchToolbarBitmapDisabled,NULL,COUNTOF(szTmp),szTmp,NULL))
      lstrcpy(szTmp,tchToolbarBitmapDisabled);
    hbmp = LoadImage(NULL,szTmp,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
  }
  if (!hbmp)
    //hbmp = CreateMappedBitmap(hInstance,(IDB_DISABLEDTOOLS),0,&tbColorMap,1);
    hbmp = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_DISABLEDTOOLS));
  GetObject(hbmp,sizeof(BITMAP),&bmp);
  himl = ImageList_Create(bmp.bmWidth/NUMTOOLBITMAPS,bmp.bmHeight,ILC_COLORDDB|ILC_MASK,0,0);
  ImageList_AddMasked(himl,hbmp,RGB(255,0,255));
  DeleteObject(hbmp);
  SendMessage(hwndToolbar,TB_SETDISABLEDIMAGELIST,0,(LPARAM)himl);

  // Load toolbar strings
  hKey = RegGetAppKey("Toolbar Strings");
  for (i = 0; i < COUNTOF(tbbMainWnd); i++) {

    if (tbbMainWnd[i].fsStyle == TBSTYLE_SEP)
      continue;

    wsprintf(tchIndex,"%02i",i+1);

    if (RegGetString(hKey,tchIndex,"",tchDesc,COUNTOF(tchDesc))) {
      tbbMainWnd[i].iString = SendMessage(hwndToolbar,TB_ADDSTRING,0,(LPARAM)tchDesc);
      tbbMainWnd[i].fsStyle |= BTNS_AUTOSIZE | BTNS_SHOWTEXT; }

    else
      tbbMainWnd[i].fsStyle &= ~(BTNS_AUTOSIZE | BTNS_SHOWTEXT);
  }
  RegCloseKey(hKey);

  SendMessage(hwndToolbar,TB_SETEXTENDEDSTYLE,0,
    SendMessage(hwndToolbar,TB_GETEXTENDEDSTYLE,0,0) | TBSTYLE_EX_MIXEDBUTTONS);

  SendMessage(hwndToolbar,TB_ADDBUTTONS,NUMINITIALTOOLS,(LPARAM)tbbMainWnd);
  SendMessage(hwndToolbar,TB_SAVERESTORE,FALSE,(LPARAM)lptbsp);
  SendMessage(hwndToolbar,TB_GETITEMRECT,0,(LPARAM)&rc);
  //SendMessage(hwndToolbar,TB_SETINDENT,2,0);

  if (bShowStatusbar)
    dwStatusbarStyle |= WS_VISIBLE;

  hwndStatus = CreateStatusWindow(dwStatusbarStyle,NULL,hwnd,IDC_STATUSBAR);

  // Create ReBar and add Toolbar
  hwndReBar = CreateWindowEx(WS_EX_TOOLWINDOW,REBARCLASSNAME,NULL,dwReBarStyle,
                             0,0,0,0,hwnd,(HMENU)IDC_REBAR,hInstance,NULL);

  rbi.cbSize = sizeof(REBARINFO);
  rbi.fMask  = 0;
  rbi.himl   = (HIMAGELIST)NULL;
  SendMessage(hwndReBar,RB_SETBARINFO,0,(LPARAM)&rbi);

  rbBand.cbSize  = sizeof(REBARBANDINFO);
  rbBand.fMask   = /*RBBIM_COLORS | RBBIM_TEXT | RBBIM_BACKGROUND | */
                   RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE /*| RBBIM_SIZE*/;
  rbBand.fStyle  = /*RBBS_CHILDEDGE |*//* RBBS_BREAK |*/ RBBS_FIXEDSIZE /*| RBBS_GRIPPERALWAYS*/;
  if (bIsAppThemed)
    rbBand.fStyle |= RBBS_CHILDEDGE;
  rbBand.hbmBack = NULL;
  rbBand.lpText     = "Toolbar";
  rbBand.hwndChild  = hwndToolbar;
  rbBand.cxMinChild = (rc.right - rc.left) * COUNTOF(tbbMainWnd);
  rbBand.cyMinChild = (rc.bottom - rc.top) + 2 * rc.top;
  rbBand.cx         = 0;
  SendMessage(hwndReBar,RB_INSERTBAND,(WPARAM)-1,(LPARAM)&rbBand);

  SetWindowPos(hwndReBar,NULL,0,0,0,0,SWP_NOZORDER);
  GetWindowRect(hwndReBar,&rc);
  cyReBar = rc.bottom - rc.top;

  cyReBarFrame = bIsAppThemed ? 0 : 2;
}


//=============================================================================
//
//  MsgThemeChanged() - Handle WM_THEMECHANGED
//
//
void MsgThemeChanged(HWND hwnd,WPARAM wParam,LPARAM lParam)
{
  RECT rc,rc2;
  TBSAVEPARAMS tbsp = { HKEY_CURRENT_USER, "Software\\Notepad2\\Toolbar", "Settings2" };
  HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);

  // reinitialize edit frame

  if (PrivateIsAppThemed()) {

    SetWindowLong(hwndEdit,GWL_EXSTYLE,GetWindowLong(hwndEdit,GWL_EXSTYLE) & ~WS_EX_CLIENTEDGE);
    SetWindowPos(hwndEdit,NULL,0,0,0,0,SWP_NOZORDER|SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE);

    SetWindowPos(hwndEditFrame,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);
    GetClientRect(hwndEditFrame,&rc);
    GetWindowRect(hwndEditFrame,&rc2);

    cxEditFrame = ((rc2.right-rc2.left) - (rc.right-rc.left)) / 2;
    cyEditFrame = ((rc2.bottom-rc2.top) - (rc.bottom-rc.top)) / 2; }

  else {

    SetWindowLong(hwndEdit,GWL_EXSTYLE,WS_EX_CLIENTEDGE|GetWindowLong(hwndEdit,GWL_EXSTYLE));
    SetWindowPos(hwndEdit,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);

    cxEditFrame = 0;
    cyEditFrame = 0; }

  // recreate toolbar and statusbar
  SendMessage(hwndToolbar,TB_SAVERESTORE,TRUE,(LPARAM)&tbsp);

  DestroyWindow(hwndToolbar);
  DestroyWindow(hwndReBar);
  DestroyWindow(hwndStatus);
  CreateBars(hwnd,hInstance,&tbsp);

  GetClientRect(hwnd,&rc);
  SendMessage(hwnd,WM_SIZE,SIZE_RESTORED,MAKELONG(rc.right,rc.bottom));
}


//=============================================================================
//
//  MsgSize() - Handles WM_SIZE
//
//
void MsgSize(HWND hwnd,WPARAM wParam,LPARAM lParam)
{

  RECT rc;
  int x,y,cx,cy;
  HDWP hdwp;

  // Statusbar
  int aWidth[6];

  if (wParam == SIZE_MINIMIZED)
    return;

  x = 0;
  y = 0;

  cx = LOWORD(lParam);
  cy = HIWORD(lParam);

  if (bShowToolbar)
  {
/*  SendMessage(hwndToolbar,WM_SIZE,0,0);
    GetWindowRect(hwndToolbar,&rc);
    y = (rc.bottom - rc.top);
    cy -= (rc.bottom - rc.top);*/

    //SendMessage(hwndToolbar,TB_GETITEMRECT,0,(LPARAM)&rc);
    SetWindowPos(hwndReBar,NULL,0,0,LOWORD(lParam),cyReBar,SWP_NOZORDER);
    // the ReBar automatically sets the correct height
    // calling SetWindowPos() with the height of one toolbar button
    // causes the control not to temporarily use the whole client area
    // and prevents flickering

    //GetWindowRect(hwndReBar,&rc);
    y = cyReBar + cyReBarFrame;    // define
    cy -= cyReBar + cyReBarFrame;  // border
  }

  if (bShowStatusbar)
  {
    SendMessage(hwndStatus,WM_SIZE,0,0);
    GetWindowRect(hwndStatus,&rc);
    cy -= (rc.bottom - rc.top);
  }

  hdwp = BeginDeferWindowPos(2);

  DeferWindowPos(hdwp,hwndEditFrame,NULL,x,y,cx,cy,
                 SWP_NOZORDER | SWP_NOACTIVATE);

  DeferWindowPos(hdwp,hwndEdit,NULL,x+cxEditFrame,y+cyEditFrame,
                 cx-2*cxEditFrame,cy-2*cyEditFrame,SWP_NOZORDER | SWP_NOACTIVATE);

  EndDeferWindowPos(hdwp);

  // Statusbar width
  aWidth[0] = max(120,min(cx/3,StatusCalcPaneWidth(hwndStatus,"Ln 9'999'999 : 9'999'999   Col 9'999'999   Sel 9'999'999")));
  aWidth[1] = aWidth[0] + StatusCalcPaneWidth(hwndStatus,"9'999'999 Bytes");
  aWidth[2] = aWidth[1] + StatusCalcPaneWidth(hwndStatus,"Unicode BE BOM");
  aWidth[3] = aWidth[2] + StatusCalcPaneWidth(hwndStatus,"CR+LF");
  aWidth[4] = aWidth[3] + StatusCalcPaneWidth(hwndStatus,"OVR");
  aWidth[5] = -1;

  SendMessage(hwndStatus,SB_SETPARTS,COUNTOF(aWidth),(LPARAM)aWidth);

  //UpdateStatusbar();

}


//=============================================================================
//
//  MsgInitMenu() - Handles WM_INITMENU
//
//
void MsgInitMenu(HWND hwnd,WPARAM wParam,LPARAM lParam)
{

  int i,i2;
  HMENU hmenu = (HMENU)wParam;

  i = lstrlen(szCurFile);
  EnableCmd(hmenu,IDM_FILE_REVERT,i);
  EnableCmd(hmenu,IDM_FILE_LAUNCH,i);
  EnableCmd(hmenu,IDM_FILE_PROPERTIES,i);
  EnableCmd(hmenu,IDM_FILE_CREATELINK,i);
  EnableCmd(hmenu,IDM_FILE_ADDTOFAV,i);

  EnableCmd(hmenu,IDM_FILE_READONLY,i);
  CheckCmd(hmenu,IDM_FILE_READONLY,bReadOnly);

  //EnableCmd(hmenu,IDM_ENCODING_UNICODEREV,!bReadOnly);
  //EnableCmd(hmenu,IDM_ENCODING_UNICODE,!bReadOnly);
  //EnableCmd(hmenu,IDM_ENCODING_UTF8SIGN,!bReadOnly);
  //EnableCmd(hmenu,IDM_ENCODING_UTF8,!bReadOnly);
  //EnableCmd(hmenu,IDM_ENCODING_ANSI,!bReadOnly);
  //EnableCmd(hmenu,IDM_LINEENDINGS_CRLF,!bReadOnly);
  //EnableCmd(hmenu,IDM_LINEENDINGS_LF,!bReadOnly);
  //EnableCmd(hmenu,IDM_LINEENDINGS_CR,!bReadOnly);

  if (iCodePage & NCP_UNICODE_REVERSE)
    i = IDM_ENCODING_UNICODEREV;
  else if (iCodePage & NCP_UNICODE)
    i = IDM_ENCODING_UNICODE;
  else if (iCodePage & NCP_UTF8_SIGN)
    i = IDM_ENCODING_UTF8SIGN;
  else if (iCodePage & NCP_UTF8)
    i = IDM_ENCODING_UTF8;
  else
    i = IDM_ENCODING_ANSI;
  CheckMenuRadioItem(hmenu,IDM_ENCODING_ANSI,IDM_ENCODING_UTF8SIGN,i,MF_BYCOMMAND);

  if (iEOLMode == SC_EOL_CRLF)
    i = IDM_LINEENDINGS_CRLF;
  else if (iEOLMode == SC_EOL_LF)
    i = IDM_LINEENDINGS_LF;
  else
    i = IDM_LINEENDINGS_CR;
  CheckMenuRadioItem(hmenu,IDM_LINEENDINGS_CRLF,IDM_LINEENDINGS_CR,i,MF_BYCOMMAND);

  EnableCmd(hmenu,IDM_FILE_RECENT,(EnumMRUList(hFileMRU,0,NULL,0) > 0));

  EnableCmd(hmenu,IDM_EDIT_UNDO,SendMessage(hwndEdit,SCI_CANUNDO,0,0) /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_REDO,SendMessage(hwndEdit,SCI_CANREDO,0,0) /*&& !bReadOnly*/);

  i = SendMessage(hwndEdit,SCI_GETSELECTIONEND,0,0) - SendMessage(hwndEdit,SCI_GETSELECTIONSTART,0,0);
  EnableCmd(hmenu,IDM_EDIT_CUT,i /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_COPY,i /*&& !bReadOnly*/);

  EnableCmd(hmenu,IDM_EDIT_COPYALL,SendMessage(hwndEdit,SCI_GETLENGTH,0,0) /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_PASTE,SendMessage(hwndEdit,SCI_CANPASTE,0,0) /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_CLEAR,i /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_CLEARALL,SendMessage(hwndEdit,SCI_GETLENGTH,0,0) /*&& !bReadOnly*/);

  //EnableCmd(hmenu,IDM_EDIT_MOVELINEUP,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_MOVELINEDOWN,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_TOGGLELINE,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_DUPLICATELINE,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_CUTLINE,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_COPYLINE,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_DELETELINE,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_DELETELINELEFT,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_DELETELINERIGHT,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_DELETEWORDLEFT,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_DELETEWORDRIGHT,!bReadOnly);

  //EnableCmd(hmenu,IDM_EDIT_INDENT,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_UNINDENT,!bReadOnly);

  //EnableCmd(hmenu,IDM_EDIT_STRIP1STCHAR,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_TRIMLINES,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_REMOVEBLANKLINES,!bReadOnly);

  EnableCmd(hmenu,IDM_EDIT_SPLITLINES,i /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_JOINLINES,i /*&& !bReadOnly*/);

  EnableCmd(hmenu,IDM_EDIT_CONVERTUPPERCASE,i /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_CONVERTLOWERCASE,i /*&& !bReadOnly*/);

  EnableCmd(hmenu,IDM_EDIT_CONVERTTABS,i /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_CONVERTSPACES,i /*&& !bReadOnly*/);

  i2 = SendMessage(hwndEdit,SCI_GETCODEPAGE,0,0);
  EnableCmd(hmenu,IDM_EDIT_CONVERTOEM,i && (i2 == iDefaultCodePage || i2 == 0) /*&& !bReadOnly*/);
  EnableCmd(hmenu,IDM_EDIT_CONVERTANSI,i && (i2 == iDefaultCodePage || i2 == 0) /*&& !bReadOnly*/);

  //EnableCmd(hmenu,IDM_EDIT_INSERT_SHORTDATE,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_INSERT_LONGDATE,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_INSERT_FILENAME,!bReadOnly);
  //EnableCmd(hmenu,IDM_EDIT_INSERT_PATHNAME,!bReadOnly);

  i = SendMessage(hwndEdit,SCI_GETLENGTH,0,0);
  EnableCmd(hmenu,IDM_EDIT_FIND,i);
  EnableCmd(hmenu,IDM_EDIT_FINDNEXT,i);
  EnableCmd(hmenu,IDM_EDIT_FINDPREV,i && lstrlen(efrData.szFind));
  EnableCmd(hmenu,IDM_EDIT_REPLACE,i /*&& !bReadOnly*/);

  CheckCmd(hmenu,IDM_VIEW_USE2NDDEFAULT,Style_GetUse2ndDefault(hwndEdit));

  CheckCmd(hmenu,IDM_VIEW_WORDWRAP,fWordWrap);
  CheckCmd(hmenu,IDM_VIEW_LONGLINEMARKER,bMarkLongLines);
  CheckCmd(hmenu,IDM_VIEW_TABSASSPACES,bTabsAsSpaces);
  CheckCmd(hmenu,IDM_VIEW_SHOWINDENTGUIDES,bShowIndentGuides);
  CheckCmd(hmenu,IDM_VIEW_AUTOINDENTTEXT,bAutoIndent);
  CheckCmd(hmenu,IDM_VIEW_LINENUMBERS,bShowLineNumbers);
  CheckCmd(hmenu,IDM_VIEW_MARGIN,bShowSelectionMargin);
  CheckCmd(hmenu,IDM_VIEW_SHOWWHITESPACE,bViewWhiteSpace);
  CheckCmd(hmenu,IDM_VIEW_SHOWEOLS,bViewEOLs);
  CheckCmd(hmenu,IDM_VIEW_WORDWRAPSYMBOLS,bShowWordWrapSymbols);
  CheckCmd(hmenu,IDM_VIEW_MATCHBRACES,bMatchBraces);
  CheckCmd(hmenu,IDM_VIEW_TOOLBAR,bShowToolbar);
  EnableCmd(hmenu,IDM_VIEW_CUSTOMIZETB,bShowToolbar);
  CheckCmd(hmenu,IDM_VIEW_STATUSBAR,bShowStatusbar);

  i = SendMessage(hwndEdit,SCI_GETLEXER,0,0);
  EnableCmd(hmenu,IDM_VIEW_AUTOCLOSETAGS,(i == SCLEX_HTML || i == SCLEX_XML));
  CheckCmd(hmenu,IDM_VIEW_AUTOCLOSETAGS,bAutoCloseTags && (i == SCLEX_HTML || i == SCLEX_XML));

  i = RegGetAppIntEx("Settings","ReuseWindow2",0);
  CheckCmd(hmenu,IDM_VIEW_REUSEWINDOW,i);
  CheckCmd(hmenu,IDM_VIEW_ALWAYSONTOP,bAlwaysOnTop);
  CheckCmd(hmenu,IDM_VIEW_MINTOTRAY,bMinimizeToTray);
  CheckCmd(hmenu,IDM_VIEW_TRANSPARENT,bTransparentMode && bTransparentModeAvailable);
  EnableCmd(hmenu,IDM_VIEW_TRANSPARENT,bTransparentModeAvailable);

  CheckCmd(hmenu,IDM_VIEW_SHOWFULLPATH,!bShortPathNames);
  CheckCmd(hmenu,IDM_VIEW_NOSAVERECENT,bSaveRecentFiles);
  CheckCmd(hmenu,IDM_VIEW_NOSAVEFINDREPL,bSaveFindReplace);
  CheckCmd(hmenu,IDM_VIEW_SAVEVEFORERUNNINGTOOLS,bSaveBeforeRunningTools);

  if (iEscFunction == 1)
    i = IDM_VIEW_ESCMINIMIZE;
  else if (iEscFunction == 2)
    i = IDM_VIEW_ESCEXIT;
  else
    i = IDM_VIEW_NOESNFUNC;
  CheckMenuRadioItem(hmenu,IDM_VIEW_ESCMINIMIZE,IDM_VIEW_NOESNFUNC,i,MF_BYCOMMAND);

  CheckCmd(hmenu,IDM_VIEW_SAVESETTINGS,bSaveSettings);

}


//=============================================================================
//
//  MsgCommand() - Handles WM_COMMAND
//
//
LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam)
{

  switch(LOWORD(wParam))
  {

    case IDM_FILE_NEW:
      FileLoad(FALSE,TRUE,FALSE,FALSE,"");
      break;


    case IDM_FILE_OPEN:
      FileLoad(FALSE,FALSE,FALSE,FALSE,"");
      break;


    case IDM_FILE_REVERT:
      {
        char tchCurFile2[MAX_PATH];

        int iCurPos    = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
        int iAnchorPos = SendMessage(hwndEdit,SCI_GETANCHOR,0,0);

        lstrcpy(tchCurFile2,szCurFile);

        if (FileLoad(FALSE,FALSE,TRUE,FALSE,tchCurFile2))
          SendMessage(hwndEdit,SCI_SETSEL,(WPARAM)iAnchorPos,(LPARAM)iCurPos);
      }
      break;


    case IDM_FILE_SAVE:
      FileSave(TRUE,FALSE,FALSE,FALSE);
      break;


    case IDM_FILE_SAVEAS:
      FileSave(TRUE,FALSE,TRUE,FALSE);
      break;


    case IDM_FILE_SAVECOPY:
      FileSave(TRUE,FALSE,TRUE,TRUE);
      break;


    case IDM_FILE_READONLY:
      //bReadOnly = (bReadOnly) ? FALSE : TRUE;
      //SendMessage(hwndEdit,SCI_SETREADONLY,bReadOnly,0);
      //UpdateToolbar();
      //UpdateStatusbar();
      if (lstrlen(szCurFile))
      {
        BOOL bSuccess = FALSE;
        DWORD dwFileAttributes = GetFileAttributes(szCurFile);
        if (dwFileAttributes != INVALID_FILE_ATTRIBUTES) {
          if (bReadOnly)
            dwFileAttributes = (dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
          else
            dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
          if (!SetFileAttributes(szCurFile,dwFileAttributes))
            MsgBox(MBWARN,IDS_READONLY_MODIFY,szCurFile); }
        else
          MsgBox(MBWARN,IDS_READONLY_MODIFY,szCurFile);

        dwFileAttributes = GetFileAttributes(szCurFile);
        if (dwFileAttributes != INVALID_FILE_ATTRIBUTES)
          bReadOnly = (dwFileAttributes & FILE_ATTRIBUTE_READONLY);

        SetWindowTitle(hwnd,uidsAppTitle,IDS_UNTITLED,szCurFile,
          bShortPathNames,bModified || iCodePage != iInitialCP,
          IDS_READONLY,bReadOnly);
      }
      break;


    case IDM_FILE_METAPATH:
      {
        SHELLEXECUTEINFO sei;
        char tchParam[MAX_PATH+4];
        char tchMetapath[MAX_PATH+4];

        lstrcpy(tchParam,szCurFile);
        PathQuoteSpaces(tchParam);

        if (!SearchPath(NULL,"metapath.exe",NULL,COUNTOF(tchMetapath),tchMetapath,NULL))
          lstrcpy(tchMetapath,"metapath.exe");

        ZeroMemory(&sei,sizeof(SHELLEXECUTEINFO));

        sei.cbSize = sizeof(SHELLEXECUTEINFO);
        sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
        sei.hwnd = hwnd;
        sei.lpVerb = NULL;
        sei.lpFile = tchMetapath;
        sei.lpParameters = tchParam;
        sei.lpDirectory = NULL;
        sei.nShow = SW_SHOWNORMAL;

        ShellExecuteEx(&sei);

        if (sei.hInstApp < 32)
          MsgBox(MBWARN,IDS_ERR_METAPATH);

        //if (32 > ShellExecute(hwnd,"",tchMetapath,tchParam,NULL,SW_SHOWNORMAL))
        //  MsgBox(MBWARN,IDS_ERR_METAPATH);

        // Set the metapath registry options if metapath.exe was found
        else
        {
          HKEY hKey;
          HKEY hKey2;

          char tchModule[MAX_PATH];
          GetModuleFileName(NULL,tchModule,COUNTOF(tchModule));

          hKey = RegGetKey("Software\\metapath\\Target Application");
          hKey2 = RegGetSubKey(hKey,PathFindFileName(tchModule));

          RegSetInt(hKey,"UseTargetApplication",1);  // enable target application
          RegSetInt(hKey,"TargetApplicationMode",1); // send wm_dropfiles
          RegSetString(hKey,"TargetApplicationPath",tchModule);
          RegSetString(hKey,"TargetApplicationWndClass",WC_NOTEPAD2);
          RegSetString(hKey,"DDEApplication","");
          RegSetString(hKey,"DDEMessage","");
          RegSetString(hKey,"DDETopic","");

          RegSetString(hKey2,"Path",tchModule);
          RegSetString(hKey2,"WndClass",WC_NOTEPAD2);
          RegSetString(hKey2,"DDEApplication","");
          RegSetString(hKey2,"DDEMessage","");
          RegSetString(hKey2,"DDETopic","");

          RegCloseKey(hKey2);
          RegCloseKey(hKey);
        }
      }
      break;


    case IDM_FILE_NEWWINDOW:
    case IDM_FILE_NEWWINDOW2:
      {
        char szModuleName[MAX_PATH];
        char szFileName[MAX_PATH];
        char szParameters[MAX_PATH+64];

        RECT rcWorkArea;
        WINDOWPLACEMENT wndpl;
        int x,y,cx,cy,imax;
        char tch[64];

        if (bSaveBeforeRunningTools && !FileSave(FALSE,TRUE,FALSE,FALSE))
          break;

        GetModuleFileName(NULL,szModuleName,COUNTOF(szModuleName));

        lstrcpy(szParameters,"-n ");

        SystemParametersInfo(SPI_GETWORKAREA,0,&rcWorkArea,0);
        wndpl.length = sizeof(WINDOWPLACEMENT);
        GetWindowPlacement(hwnd,&wndpl);

        // offset new window position +10/+10
        x = wndpl.rcNormalPosition.left + 10;
        y = wndpl.rcNormalPosition.top  + 10;
        cx = wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left;
        cy = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top;

        // check if window fits work area
        if (x + cx > rcWorkArea.right - rcWorkArea.left ||
            y + cy > rcWorkArea.bottom - rcWorkArea.top)
          x = y = 0;

        imax = IsZoomed(hwnd);

        wsprintf(tch,"-p %i,%i,%i,%i,%i",x,y,cx,cy,imax);
        lstrcat(szParameters,tch);

        if (LOWORD(wParam) != IDM_FILE_NEWWINDOW2 && lstrlen(szCurFile)) {
          lstrcpy(szFileName,szCurFile);
          PathQuoteSpaces(szFileName);
          lstrcat(szParameters," ");
          lstrcat(szParameters,szFileName); }

        ShellExecute(hwnd,NULL,szModuleName,szParameters,NULL,SW_SHOWNORMAL);
      }
      break;


    case IDM_FILE_LAUNCH:
      {
        SHELLEXECUTEINFO sei;

        if (!lstrlen(szCurFile))
          break;

        if (bSaveBeforeRunningTools && !FileSave(FALSE,TRUE,FALSE,FALSE))
          break;

        ZeroMemory(&sei,sizeof(SHELLEXECUTEINFO));

        sei.cbSize = sizeof(SHELLEXECUTEINFO);
        sei.fMask = SEE_MASK_NOCLOSEPROCESS;
        sei.hwnd = hwnd;
        sei.lpVerb = NULL;
        sei.lpFile = szCurFile;
        sei.lpParameters = NULL;
        sei.lpDirectory = NULL;
        sei.nShow = SW_SHOWNORMAL;

        ShellExecuteEx(&sei);
      }
      break;


    case IDM_FILE_RUN:
      {
        char tchCmdLine[MAX_PATH+4];

        if (bSaveBeforeRunningTools && !FileSave(FALSE,TRUE,FALSE,FALSE))
          break;

        lstrcpy(tchCmdLine,szCurFile);
        PathQuoteSpaces(tchCmdLine);

        RunDlg(hwnd,tchCmdLine);
      }
      break;


    case IDM_FILE_OPENWITH:
      if (bSaveBeforeRunningTools && !FileSave(FALSE,TRUE,FALSE,FALSE))
        break;
      OpenWithDlg(hwnd,szCurFile);
      break;


    case IDM_FILE_PAGESETUP:
      EditPrintSetup(hwndEdit);
      break;

    case IDM_FILE_PRINT:
      {
        SHFILEINFO shfi;
        char *pszTitle;
        char tchUntitled[32];
        char tchPageFmt[32];

        if (lstrlen(szCurFile)) {
          SHGetFileInfo2(szCurFile,0,&shfi,sizeof(SHFILEINFO),SHGFI_DISPLAYNAME);
          pszTitle = shfi.szDisplayName; }
        else {
          GetString(IDS_UNTITLED,tchUntitled,COUNTOF(tchUntitled));
          pszTitle = tchUntitled; }

        GetString(IDS_PRINT_PAGENUM,tchPageFmt,COUNTOF(tchPageFmt));

        if (!EditPrint(hwndEdit,pszTitle,tchPageFmt))
          MsgBox(MBWARN,IDS_PRINT_ERROR);
      }
      break;


    case IDM_FILE_PROPERTIES:
      {
        SHELLEXECUTEINFO sei;

        if (lstrlen(szCurFile) == 0)
          break;

        ZeroMemory(&sei,sizeof(SHELLEXECUTEINFO));

        sei.cbSize = sizeof(SHELLEXECUTEINFO);
        sei.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_NOCLOSEPROCESS;
        sei.hwnd = hwnd;
        sei.lpVerb = "properties";
        sei.lpFile = szCurFile;
        sei.nShow = SW_SHOWNORMAL;

        ShellExecuteEx(&sei);
      }
      break;

    case IDM_FILE_CREATELINK:
      {
        if (!lstrlen(szCurFile))
          break;

        if (!PathCreateDeskLnk(szCurFile))
          MsgBox(MBWARN,IDS_ERR_CREATELINK);
      }
      break;


    case IDM_FILE_OPENFAV:
      if (FileSave(FALSE,TRUE,FALSE,FALSE)) {
        char tchFile[MAX_PATH];
        if (FavoritesDlg(hwnd,tchFile))
          FileLoad(TRUE,FALSE,FALSE,FALSE,tchFile); }
      break;


    case IDM_FILE_ADDTOFAV:
      if (lstrlen(szCurFile)) {
        SHFILEINFO shfi;
        SHGetFileInfo2(szCurFile,0,&shfi,sizeof(SHFILEINFO),SHGFI_DISPLAYNAME);
        AddToFavDlg(hwnd,shfi.szDisplayName,szCurFile); }
      break;


    case IDM_FILE_MANAGEFAV:
      {
        SHELLEXECUTEINFO sei;
        ZeroMemory(&sei,sizeof(SHELLEXECUTEINFO));

        sei.cbSize = sizeof(SHELLEXECUTEINFO);
        sei.fMask = SEE_MASK_NOCLOSEPROCESS;
        sei.hwnd = hwnd;
        sei.lpVerb = NULL;
        sei.lpFile = tchFavoritesDir;
        sei.lpParameters = NULL;
        sei.lpDirectory = NULL;
        sei.nShow = SW_SHOWNORMAL;

        // Run favorites directory
        ShellExecuteEx(&sei);
      }
      break;


    case IDM_FILE_RECENT:
      if (EnumMRUList(hFileMRU,0,NULL,0) > 0) {
        if (FileSave(FALSE,TRUE,FALSE,FALSE)) {
          char tchFile[MAX_PATH];
          if (FileMRUDlg(hwnd,tchFile))
            FileLoad(TRUE,FALSE,FALSE,FALSE,tchFile); } }
      break;


    case IDM_FILE_EXIT:
      SendMessage(hwnd,WM_CLOSE,0,0);
      break;


    case IDM_ENCODING_ANSI:
    case IDM_ENCODING_UNICODE:
    case IDM_ENCODING_UNICODEREV:
    case IDM_ENCODING_UTF8:
    case IDM_ENCODING_UTF8SIGN:
      {
        int iNewCodePage = iEncodings[LOWORD(wParam)-IDM_ENCODING_ANSI];
        if (SendMessage(hwndEdit,SCI_GETLENGTH,0,0) == 0)
        {
          iCodePage = iNewCodePage;
          iInitialCP = iNewCodePage;
          SendMessage(hwndEdit,SCI_SETCODEPAGE,(iCodePage == NCP_DEFAULT) ? iDefaultCodePage : SC_CP_UTF8,0);
          UpdateToolbar();
          UpdateStatusbar();
          SetWindowTitle(hwnd,uidsAppTitle,IDS_UNTITLED,szCurFile,
            bShortPathNames,bModified || iCodePage != iInitialCP,
            IDS_READONLY,bReadOnly);
        }
        else if (iCodePage != iNewCodePage)
        {
          if ((iCodePage != 0 && iNewCodePage != 0) || (IDYES == MsgBox(MBYESNO,IDS_ASK_ENCODING)))
          {
            iCodePage = iNewCodePage;
            SendMessage(hwndEdit,SCI_SETCODEPAGE,(iCodePage == NCP_DEFAULT) ? iDefaultCodePage : SC_CP_UTF8,0);
          }
          UpdateToolbar();
          UpdateStatusbar();
          SetWindowTitle(hwnd,uidsAppTitle,IDS_UNTITLED,szCurFile,
            bShortPathNames,bModified || iCodePage != iInitialCP,
            IDS_READONLY,bReadOnly);
        }
      }
      break;


    case IDM_ENCODING_SETDEFAULT:
      if (SelectOptionDlg(hwnd,IDD_ENCODING,&iDefaultEncoding)) {
        if (bAutoSelACP) {
          if (SendMessage(hwndEdit,SCI_GETCODEPAGE,0,0) != SC_CP_UTF8)
            Style_SetACPfromCharSet(hwndEdit); }
        else { char tch[64];
          // Reload from Registry
          HKEY hKey = RegGetAppKey("International");
          iDefaultCodePage = RegGetInt(hKey,"CodePage",GetACP()/* default */);
          RegCloseKey(hKey);
          wsprintf(tch,"ACP = %i",iDefaultCodePage);
          MessageBox(hwnd,tch,"",0);
          if (SendMessage(hwndEdit,SCI_GETCODEPAGE,0,0) != SC_CP_UTF8)
            SendMessage(hwndEdit,SCI_SETCODEPAGE,(WPARAM)iDefaultCodePage,0); } }
      break;


    case IDM_LINEENDINGS_CRLF:
    case IDM_LINEENDINGS_LF:
    case IDM_LINEENDINGS_CR:
      {
        int iNewEOLMode = iLineEndings[LOWORD(wParam)-IDM_LINEENDINGS_CRLF];

        iEOLMode = iNewEOLMode;
        SendMessage(hwndEdit,SCI_SETEOLMODE,iEOLMode,0);
        SendMessage(hwndEdit,SCI_CONVERTEOLS,iEOLMode,0);
        UpdateToolbar();
        UpdateStatusbar();
        SetWindowTitle(hwnd,uidsAppTitle,IDS_UNTITLED,szCurFile,
          bShortPathNames,bModified || iCodePage != iInitialCP,
          IDS_READONLY,bReadOnly);
      }
      break;


    case IDM_LINEENDINGS_SETDEFAULT:
      SelectOptionDlg(hwnd,IDD_EOLMODE,&iDefaultEOLMode);
      break;


    case IDM_EDIT_UNDO:
      SendMessage(hwndEdit,SCI_UNDO,0,0);
      break;


    case IDM_EDIT_REDO:
      SendMessage(hwndEdit,SCI_REDO,0,0);
      break;


    case IDM_EDIT_CUT:
      if (flagPasteBoard)
        bLastCopyFromMe = TRUE;
      SendMessage(hwndEdit,SCI_CUT,0,0);
      break;


    case IDM_EDIT_COPY:
      if (flagPasteBoard)
        bLastCopyFromMe = TRUE;
      SendMessage(hwndEdit,SCI_COPY,0,0);
      UpdateToolbar();
      break;


    case IDM_EDIT_COPYALL:
      if (flagPasteBoard)
        bLastCopyFromMe = TRUE;
      SendMessage(hwndEdit,SCI_COPYRANGE,0,SendMessage(hwndEdit,SCI_GETLENGTH,0,0));
      UpdateToolbar();
      break;


    case IDM_EDIT_PASTE:
      SendMessage(hwndEdit,SCI_PASTE,0,0);
      break;


    case IDM_EDIT_CLEAR:
      SendMessage(hwndEdit,SCI_CLEAR,0,0);
      break;


    case IDM_EDIT_CLEARALL:
      SendMessage(hwndEdit,SCI_CLEARALL,0,0);
      break;


    case IDM_EDIT_SELECTALL:
      SendMessage(hwndEdit,SCI_SELECTALL,0,0);
      //SendMessage(hwndEdit,SCI_SETSEL,0,(LPARAM)-1);
      break;


    case IDM_EDIT_SELECTWORD:
      {
        int iPos = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);

        int iWordStart = SendMessage(hwndEdit,SCI_WORDSTARTPOSITION,iPos,TRUE);
        int iWordEnd   = SendMessage(hwndEdit,SCI_WORDENDPOSITION,iPos,TRUE);

        if (iWordStart == iWordEnd) // we are in whitespace salad...
        {
          iWordStart = SendMessage(hwndEdit,SCI_WORDENDPOSITION,iPos,FALSE);
          iWordEnd   = SendMessage(hwndEdit,SCI_WORDENDPOSITION,iWordStart,TRUE);
          if (iWordStart != iWordEnd)
            SendMessage(hwndEdit,SCI_SETSEL,iWordStart,iWordEnd);
        }
        else
          SendMessage(hwndEdit,SCI_SETSEL,iWordStart,iWordEnd);
      }
      break;


    case IDM_EDIT_MOVELINEUP:
      {
        int iCurPos  = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
        int iCurLine = SendMessage(hwndEdit,SCI_LINEFROMPOSITION,(WPARAM)iCurPos,0);
        int iLinePos = iCurPos - SendMessage(hwndEdit,SCI_POSITIONFROMLINE,(WPARAM)iCurLine,0);
        if (iCurLine > 0) {
          SendMessage(hwndEdit,SCI_BEGINUNDOACTION,0,0);
          SendMessage(hwndEdit,SCI_LINETRANSPOSE,0,0);
          //SendMessage(hwndEdit,SCI_GOTOLINE,(WPARAM)iCurLine-1,0);
          SendMessage(hwndEdit,SCI_GOTOPOS,(WPARAM)SendMessage(hwndEdit,SCI_POSITIONFROMLINE,(WPARAM)iCurLine-1,0)+iLinePos,0);
          SendMessage(hwndEdit,SCI_CHOOSECARETX,0,0);
          SendMessage(hwndEdit,SCI_ENDUNDOACTION,0,0); }
      }
      break;


    case IDM_EDIT_MOVELINEDOWN:
      {
        int iCurPos  = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
        int iCurLine = SendMessage(hwndEdit,SCI_LINEFROMPOSITION,(WPARAM)iCurPos,0);
        int iLinePos = iCurPos - SendMessage(hwndEdit,SCI_POSITIONFROMLINE,(WPARAM)iCurLine,0);
        if (iCurLine < SendMessage(hwndEdit,SCI_GETLINECOUNT,0,0) - 1) {
          SendMessage(hwndEdit,SCI_BEGINUNDOACTION,0,0);
          SendMessage(hwndEdit,SCI_GOTOLINE,(WPARAM)iCurLine+1,0);
          SendMessage(hwndEdit,SCI_LINETRANSPOSE,0,0);
          SendMessage(hwndEdit,SCI_GOTOPOS,(WPARAM)SendMessage(hwndEdit,SCI_POSITIONFROMLINE,(WPARAM)iCurLine+1,0)+iLinePos,0);
          SendMessage(hwndEdit,SCI_CHOOSECARETX,0,0);
          SendMessage(hwndEdit,SCI_ENDUNDOACTION,0,0); }
      }
      break;


    case IDM_EDIT_TOGGLELINE:
      {
        int iCurPos  = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
        int iCurLine = SendMessage(hwndEdit,SCI_LINEFROMPOSITION,(WPARAM)iCurPos,0);
        int iCol = SendMessage(hwndEdit,SCI_GETCOLUMN,iCurPos,0) + 1;
        SendMessage(hwndEdit,SCI_BEGINUNDOACTION,0,0);
        SendMessage(hwndEdit,SCI_LINETRANSPOSE,0,0);
        EditJumpTo(hwndEdit,iCurLine+1,iCol);
        SendMessage(hwndEdit,SCI_ENDUNDOACTION,0,0);
      }
      break;


    case IDM_EDIT_DUPLICATELINE:
      SendMessage(hwndEdit,SCI_LINEDUPLICATE,0,0);
      break;


    case IDM_EDIT_CUTLINE:
      if (flagPasteBoard)
        bLastCopyFromMe = TRUE;
      SendMessage(hwndEdit,SCI_LINECUT,0,0);
      break;


    case IDM_EDIT_COPYLINE:
      if (flagPasteBoard)
        bLastCopyFromMe = TRUE;
      SendMessage(hwndEdit,SCI_LINECOPY,0,0);
      UpdateToolbar();
      break;


    case IDM_EDIT_DELETELINE:
      SendMessage(hwndEdit,SCI_LINEDELETE,0,0);
      break;


    case IDM_EDIT_DELETELINELEFT:
      SendMessage(hwndEdit,SCI_DELLINELEFT,0,0);
      break;


    case IDM_EDIT_DELETELINERIGHT:
      SendMessage(hwndEdit,SCI_DELLINERIGHT,0,0);
      break;


    //case IDM_EDIT_DELETEWORDLEFT:
    //  SendMessage(hwndEdit,SCI_DELWORDLEFT,0,0);
    //  break;


    //case IDM_EDIT_DELETEWORDRIGHT:
    //  SendMessage(hwndEdit,SCI_DELWORDRIGHT,0,0);
    //  break;


    case IDM_EDIT_INDENT:
      SendMessage(hwndEdit,SCI_TAB,0,0);
      break;


    case IDM_EDIT_UNINDENT:
      SendMessage(hwndEdit,SCI_BACKTAB,0,0);
      break;


    case IDM_EDIT_STRIP1STCHAR:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      EditStripFirstCharacter(hwndEdit);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_TRIMLINES:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      EditStripTrailingBlanks(hwndEdit);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_REMOVEBLANKLINES:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      EditRemoveBlankLines(hwndEdit);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_SPLITLINES:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      SendMessage(hwndEdit,SCI_TARGETFROMSELECTION,0,0);
      SendMessage(hwndEdit,SCI_LINESSPLIT,0,0);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_JOINLINES:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      SendMessage(hwndEdit,SCI_TARGETFROMSELECTION,0,0);
      SendMessage(hwndEdit,SCI_LINESJOIN,0,0);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_FINDMATCHINGBRACE:
      {
        int iBrace2 = -1;
        int iPos = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
        char c = (char)SendMessage(hwndEdit,SCI_GETCHARAT,iPos,0);
        if (StrChr("()[]{}",c))
          iBrace2 = SendMessage(hwndEdit,SCI_BRACEMATCH,iPos,0);
        // Try one before
        else {
          iPos = SendMessage(hwndEdit,SCI_POSITIONBEFORE,iPos,0);
          c = (char)SendMessage(hwndEdit,SCI_GETCHARAT,iPos,0);
          if (StrChr("()[]{}",c))
            iBrace2 = SendMessage(hwndEdit,SCI_BRACEMATCH,iPos,0);
        }
        if (iBrace2 != -1)
          SendMessage(hwndEdit,SCI_GOTOPOS,(WPARAM)iBrace2,0);
      }
      break;


    case IDM_EDIT_SELTOMATCHINGBRACE:
      {
        int iBrace2 = -1;
        int iPos = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
        char c = (char)SendMessage(hwndEdit,SCI_GETCHARAT,iPos,0);
        if (StrChr("()[]{}",c))
          iBrace2 = SendMessage(hwndEdit,SCI_BRACEMATCH,iPos,0);
        // Try one before
        else {
          iPos = SendMessage(hwndEdit,SCI_POSITIONBEFORE,iPos,0);
          c = (char)SendMessage(hwndEdit,SCI_GETCHARAT,iPos,0);
          if (StrChr("()[]{}",c))
            iBrace2 = SendMessage(hwndEdit,SCI_BRACEMATCH,iPos,0);
        }
        if (iBrace2 != -1) {
          if (iBrace2 > iPos)
            SendMessage(hwndEdit,SCI_SETSEL,(WPARAM)iPos,(LPARAM)iBrace2+1);
          else
            SendMessage(hwndEdit,SCI_SETSEL,(WPARAM)iPos+1,(LPARAM)iBrace2); }
      }
      break;


    case IDM_EDIT_GOTOLINE:
      EditLinenumDlg(hwndEdit);
      break;


    case IDM_EDIT_CONVERTUPPERCASE:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      EditMakeUppercase(hwndEdit);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_CONVERTLOWERCASE:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      EditMakeLowercase(hwndEdit);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_CONVERTTABS:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      EditTabsToSpaces(hwndEdit,iTabWidth);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_CONVERTSPACES:
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
      EditSpacesToTabs(hwndEdit,iTabWidth);
      SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
      break;


    case IDM_EDIT_CONVERTANSI:
      {
        int iCurPos    = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
        int iAnchorPos = SendMessage(hwndEdit,SCI_GETANCHOR,0,0);
        if (iCurPos != iAnchorPos)
        {
          if (SC_SEL_RECTANGLE != SendMessage(hwndEdit,SCI_GETSELECTIONMODE,0,0))
          {
            int iSelCount = SendMessage(hwndEdit,SCI_GETSELECTIONEND,0,0) -
                              SendMessage(hwndEdit,SCI_GETSELECTIONSTART,0,0);
            char *pszOEM = GlobalAlloc(GPTR,iSelCount+2);
            char *pszANSI = GlobalAlloc(GPTR,iSelCount+2);
            SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
            SendMessage(hwndEdit,SCI_GETSELTEXT,0,(LPARAM)pszOEM);
            OemToCharBuff(pszOEM,pszANSI,GlobalSize(pszANSI));
            SendMessage(hwndEdit,SCI_BEGINUNDOACTION,0,0);
            SendMessage(hwndEdit,SCI_CLEAR,0,0);
            SendMessage(hwndEdit,SCI_ADDTEXT,(WPARAM)iSelCount,(LPARAM)pszANSI);
            SendMessage(hwndEdit,SCI_SETSEL,(WPARAM)iAnchorPos,(LPARAM)iCurPos);
            SendMessage(hwndEdit,SCI_ENDUNDOACTION,0,0);
            GlobalFree(pszOEM);
            GlobalFree(pszANSI);
            SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
          }
          else
            MsgBox(MBINFO,IDS_SELRECT);
        }
      }
      break;


    case IDM_EDIT_CONVERTOEM:
      {
        int iCurPos    = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
        int iAnchorPos = SendMessage(hwndEdit,SCI_GETANCHOR,0,0);
        if (iCurPos != iAnchorPos)
        {
          if (SC_SEL_RECTANGLE != SendMessage(hwndEdit,SCI_GETSELECTIONMODE,0,0))
          {
            int iSelCount = SendMessage(hwndEdit,SCI_GETSELECTIONEND,0,0) -
                              SendMessage(hwndEdit,SCI_GETSELECTIONSTART,0,0);
            char *pszANSI = GlobalAlloc(GPTR,iSelCount+2);
            char *pszOEM = GlobalAlloc(GPTR,iSelCount+2);
            SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORWAIT,0);
            SendMessage(hwndEdit,SCI_GETSELTEXT,0,(LPARAM)pszANSI);
            CharToOemBuff(pszANSI,pszOEM,GlobalSize(pszOEM));
            SendMessage(hwndEdit,SCI_BEGINUNDOACTION,0,0);
            SendMessage(hwndEdit,SCI_CLEAR,0,0);
            SendMessage(hwndEdit,SCI_ADDTEXT,(WPARAM)iSelCount,(LPARAM)pszOEM);
            SendMessage(hwndEdit,SCI_SETSEL,(WPARAM)iAnchorPos,(LPARAM)iCurPos);
            SendMessage(hwndEdit,SCI_ENDUNDOACTION,0,0);
            GlobalFree(pszANSI);
            GlobalFree(pszOEM);
            SendMessage(hwndEdit,SCI_SETCURSOR,SC_CURSORNORMAL,0);
          }
          else
            MsgBox(MBINFO,IDS_SELRECT);
        }
      }
      break;


    case IDM_EDIT_INSERT_SHORTDATE:
    case IDM_EDIT_INSERT_LONGDATE:
      {
        //if (!bReadOnly)
        //{
          char tchDate[128];
          char tchTime[128];
          char tchDateTime[256];
          SYSTEMTIME st;

          GetLocalTime(&st);
          GetDateFormat(LOCALE_USER_DEFAULT,(
            LOWORD(wParam) == IDM_EDIT_INSERT_SHORTDATE) ? DATE_SHORTDATE : DATE_LONGDATE,
            &st,NULL,tchDate,COUNTOF(tchDate));
          GetTimeFormat(LOCALE_USER_DEFAULT,TIME_NOSECONDS,&st,NULL,tchTime,COUNTOF(tchTime));

          wsprintf(tchDateTime,"%s %s",tchTime,tchDate);

          SendMessage(hwndEdit,SCI_REPLACESEL,0,(LPARAM)tchDateTime);
        //}
      }
      break;


    case IDM_EDIT_INSERT_FILENAME:
    case IDM_EDIT_INSERT_PATHNAME:
      {
        //if (!bReadOnly)
        //{
          SHFILEINFO shfi;
          char *pszInsert;
          char tchUntitled[32];

          if (lstrlen(szCurFile)) {
            if (LOWORD(wParam) == IDM_EDIT_INSERT_FILENAME) {
              SHGetFileInfo2(szCurFile,0,&shfi,sizeof(SHFILEINFO),SHGFI_DISPLAYNAME);
              pszInsert = shfi.szDisplayName; }
            else
              pszInsert = szCurFile; }

          else {
            GetString(IDS_UNTITLED,tchUntitled,COUNTOF(tchUntitled));
            pszInsert = tchUntitled; }

          SendMessage(hwndEdit,SCI_REPLACESEL,0,(LPARAM)pszInsert);
        //}
      }
      break;


    case IDM_EDIT_BOOKMARK_NEXT:
      EditJumpToBookmark(hwndEdit,TRUE);
      break;


    case IDM_EDIT_BOOKMARK_PREV:
      EditJumpToBookmark(hwndEdit,FALSE);
      break;


    case IDM_EDIT_BOOKMARK_TOGGLE:
      EditToggleBookmark(hwndEdit);
      break;


    case IDM_EDIT_BOOKMARK_CLEARALL:
      EditClearAllBookmarks(hwndEdit);
      break;


    case IDM_EDIT_FIND:
      EditFindReplaceDlg(hwndEdit,&efrData,FALSE);
      cpLastFind = SendMessage(hwndEdit,SCI_GETCODEPAGE,0,0);
      break;


    case IDM_EDIT_FINDNEXT:
      if (IsWindowsNT()) {
        UINT cp = SendMessage(hwndEdit,SCI_GETCODEPAGE,0,0);
        if (cpLastFind != cp) {
          if (cp != SC_CP_UTF8) {
            WCHAR wszFind[256];
            MultiByteToWideChar(CP_UTF8,0,efrData.szFindUTF8,-1,wszFind,COUNTOF(wszFind));
            WideCharToMultiByte(cp,0,wszFind,-1,efrData.szFind,COUNTOF(efrData.szFind),NULL,NULL); }
          else
            lstrcpy(efrData.szFind,efrData.szFindUTF8); }
          cpLastFind = cp; }
      EditFindNext(hwndEdit,&efrData);
      break;


    case IDM_EDIT_FINDPREV:
      if (IsWindowsNT()) {
        UINT cp = SendMessage(hwndEdit,SCI_GETCODEPAGE,0,0);
        if (cpLastFind != cp) {
          if (cp != SC_CP_UTF8) {
            WCHAR wszFind[256];
            MultiByteToWideChar(CP_UTF8,0,efrData.szFindUTF8,-1,wszFind,COUNTOF(wszFind));
            WideCharToMultiByte(cp,0,wszFind,-1,efrData.szFind,COUNTOF(efrData.szFind),NULL,NULL); }
          else
            lstrcpy(efrData.szFind,efrData.szFindUTF8); }
          cpLastFind = cp; }
      EditFindPrev(hwndEdit,&efrData);
      break;


    case IDM_EDIT_REPLACE:
      EditFindReplaceDlg(hwndEdit,&efrData,TRUE);
      cpLastFind = SendMessage(hwndEdit,SCI_GETCODEPAGE,0,0);
      break;


    case IDM_VIEW_SCHEME:
      Style_SelectLexerDlg(hwndEdit);
      UpdateStatusbar();
      UpdateLineNumberWidth();
      break;


    case IDM_VIEW_USE2NDDEFAULT:
      Style_ToggleUse2ndDefault(hwndEdit);
      UpdateStatusbar();
      UpdateLineNumberWidth();
      break;


    case IDM_VIEW_SCHEMECONFIG:
      Style_ConfigDlg(hwndEdit);
      UpdateStatusbar();
      UpdateLineNumberWidth();
      break;


    case IDM_VIEW_WORDWRAP:
      fWordWrap = (fWordWrap) ? FALSE : TRUE;
      SendMessage(hwndEdit,SCI_SETWRAPMODE,(fWordWrap)?SC_WRAP_WORD:SC_WRAP_NONE,0);
      UpdateToolbar();
      break;


    case IDM_VIEW_WORDWRAPSETTINGS:
      if (WordWrapSettingsDlg(hwnd,IDD_WORDWRAP,&iWordWrapIndent))
      {
        iWordWrapIndent = max(min(iWordWrapIndent,1024),0);
        SendMessage(hwndEdit,SCI_SETWRAPSTARTINDENT,iWordWrapIndent,0);

        if (bShowWordWrapSymbols) {
          SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGSLOCATION,WrapSymbols[iWordWrapSymbols].location,0);
          SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGS,WrapSymbols[iWordWrapSymbols].flags,0); }
        else {
          SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGS,0,0); }
      }
      break;


    case IDM_VIEW_LONGLINEMARKER:
      bMarkLongLines = (bMarkLongLines) ? FALSE: TRUE;
      if (bMarkLongLines) {
        SendMessage(hwndEdit,SCI_SETEDGEMODE,(iLongLineMode == EDGE_LINE)?EDGE_LINE:EDGE_BACKGROUND,0);
        Style_SetLongLineColors(hwndEdit); }
      else
        SendMessage(hwndEdit,SCI_SETEDGEMODE,EDGE_NONE,0);
      break;


    case IDM_VIEW_LONGLINESETTINGS:
      if (LongLineSettingsDlg(hwnd,IDD_LONGLINES,&iLongLinesLimit))
      {
        bMarkLongLines = TRUE;
        SendMessage(hwndEdit,SCI_SETEDGEMODE,(iLongLineMode == EDGE_LINE)?EDGE_LINE:EDGE_BACKGROUND,0);
        Style_SetLongLineColors(hwndEdit);
        iLongLinesLimit = max(min(iLongLinesLimit,1024),0);
        SendMessage(hwndEdit,SCI_SETEDGECOLUMN,iLongLinesLimit,0);
      }
      break;


    case IDM_VIEW_TABSASSPACES:
      bTabsAsSpaces = (bTabsAsSpaces) ? FALSE : TRUE;
      SendMessage(hwndEdit,SCI_SETUSETABS,!bTabsAsSpaces,0);
      break;


    case IDM_VIEW_TABSETTINGS:
      if (TabSettingsDlg(hwnd,IDD_TABSETTINGS,&iTabWidth))
      {
        SendMessage(hwndEdit,SCI_SETUSETABS,!bTabsAsSpaces,0);
        iTabWidth = max(min(iTabWidth,24),1);
        SendMessage(hwndEdit,SCI_SETTABWIDTH,iTabWidth,0);
        SendMessage(hwndEdit,SCI_SETINDENT,0,0);
      }
      break;


    case IDM_VIEW_SHOWINDENTGUIDES:
      bShowIndentGuides = (bShowIndentGuides) ? FALSE : TRUE;
      SendMessage(hwndEdit,SCI_SETINDENTATIONGUIDES,bShowIndentGuides,0);
      break;


    case IDM_VIEW_AUTOINDENTTEXT:
      bAutoIndent = (bAutoIndent) ? FALSE : TRUE;
      break;


    case IDM_VIEW_LINENUMBERS:
      bShowLineNumbers = (bShowLineNumbers) ? FALSE : TRUE;
      UpdateLineNumberWidth();
      //SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,0,
      //  (bShowLineNumbers)?SendMessage(hwndEdit,SCI_TEXTWIDTH,STYLE_LINENUMBER,(LPARAM)"_999999_"):0);
      break;


    case IDM_VIEW_MARGIN:
      bShowSelectionMargin = (bShowSelectionMargin) ? FALSE : TRUE;
      SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,1,(bShowSelectionMargin)?16:0);
      break;


    case IDM_VIEW_SHOWWHITESPACE:
      bViewWhiteSpace = (bViewWhiteSpace) ? FALSE : TRUE;
      SendMessage(hwndEdit,SCI_SETVIEWWS,(bViewWhiteSpace)?SCWS_VISIBLEALWAYS:SCWS_INVISIBLE,0);
      break;


    case IDM_VIEW_SHOWEOLS:
      bViewEOLs = (bViewEOLs) ? FALSE : TRUE;
      SendMessage(hwndEdit,SCI_SETVIEWEOL,bViewEOLs,0);
      break;


    case IDM_VIEW_WORDWRAPSYMBOLS:
      bShowWordWrapSymbols = (bShowWordWrapSymbols) ? 0 : 1;
      if (bShowWordWrapSymbols) {
        SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGSLOCATION,WrapSymbols[iWordWrapSymbols].location,0);
        SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGS,WrapSymbols[iWordWrapSymbols].flags,0); }
      else {
        SendMessage(hwndEdit,SCI_SETWRAPVISUALFLAGS,0,0); }
      break;


    case IDM_VIEW_MATCHBRACES:
      bMatchBraces = (bMatchBraces) ? FALSE : TRUE;
      if (!bMatchBraces)
        SendMessage(hwndEdit,SCI_BRACEHIGHLIGHT,(WPARAM)-1,(LPARAM)-1);
      break;


    case IDM_VIEW_AUTOCLOSETAGS:
      bAutoCloseTags = (bAutoCloseTags) ? FALSE : TRUE;
      break;


    case IDM_VIEW_ZOOMIN:
      SendMessage(hwndEdit,SCI_ZOOMIN,0,0);
      //UpdateLineNumberWidth();
      break;


    case IDM_VIEW_ZOOMOUT:
      SendMessage(hwndEdit,SCI_ZOOMOUT,0,0);
      //UpdateLineNumberWidth();
      break;


    case IDM_VIEW_RESETZOOM:
      SendMessage(hwndEdit,SCI_SETZOOM,0,0);
      //UpdateLineNumberWidth();
      break;


    case IDM_VIEW_TOOLBAR:
      if (bShowToolbar) {
        bShowToolbar = 0;
        ShowWindow(hwndReBar,SW_HIDE); }
      else {
        bShowToolbar = 1;
        UpdateToolbar();
        ShowWindow(hwndReBar,SW_SHOW); }
      SendWMSize(hwnd);
      break;


    case IDM_VIEW_CUSTOMIZETB:
      SendMessage(hwndToolbar,TB_CUSTOMIZE,0,0);
      break;


    case IDM_VIEW_STATUSBAR:
      if (bShowStatusbar) {
        bShowStatusbar = 0;
        ShowWindow(hwndStatus,SW_HIDE); }
      else {
        bShowStatusbar = 1;
        UpdateStatusbar();
        ShowWindow(hwndStatus,SW_SHOW); }
      SendWMSize(hwnd);
      break;


    case IDM_VIEW_REUSEWINDOW:
      if (RegGetAppIntEx("Settings","ReuseWindow2",0))
        RegSetAppIntEx("Settings","ReuseWindow2",0);
      else
        RegSetAppIntEx("Settings","ReuseWindow2",1);
      break;


    case IDM_VIEW_ALWAYSONTOP:
      if (bAlwaysOnTop) {
        bAlwaysOnTop = 0;
        SetWindowPos(hwnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); }
      else {
        bAlwaysOnTop = 1;
        SetWindowPos(hwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); }
      break;


    case IDM_VIEW_MINTOTRAY:
      bMinimizeToTray =(bMinimizeToTray) ? FALSE : TRUE;
      break;


    case IDM_VIEW_TRANSPARENT:
      bTransparentMode =(bTransparentMode) ? FALSE : TRUE;
      SetWindowTransparentMode(hwnd,bTransparentMode);
      break;


    case IDM_VIEW_SHOWFULLPATH:
      bShortPathNames = (bShortPathNames) ? FALSE : TRUE;
      SetWindowTitle(hwnd,uidsAppTitle,IDS_UNTITLED,szCurFile,
        bShortPathNames,bModified || iCodePage != iInitialCP,
        IDS_READONLY,bReadOnly);
      break;


    case IDM_VIEW_NOSAVERECENT:
      bSaveRecentFiles = (bSaveRecentFiles) ? FALSE : TRUE;
      break;


    case IDM_VIEW_NOSAVEFINDREPL:
      bSaveFindReplace = (bSaveFindReplace) ? FALSE : TRUE;
      break;


    case IDM_VIEW_SAVEVEFORERUNNINGTOOLS:
      bSaveBeforeRunningTools = (bSaveBeforeRunningTools) ? FALSE : TRUE;
      break;


    case IDM_VIEW_ESCMINIMIZE:
      iEscFunction = 1;
      break;



    case IDM_VIEW_ESCEXIT:
      iEscFunction = 2;
      break;


    case IDM_VIEW_NOESNFUNC:
      iEscFunction = 0;
      break;


    case IDM_VIEW_SAVESETTINGS:
      bSaveSettings = (bSaveSettings) ? FALSE : TRUE;
      break;


    case IDM_VIEW_SAVESETTINGSNOW:
      SaveSettings(TRUE);
      MsgBox(MBINFO,IDS_SAVESETTINGS);
      break;


    case IDM_HELP_ABOUT:
      DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_ABOUT),
        hwnd,AboutDlgProc);
      break;


    case CMD_ESCAPE:
      if (iEscFunction == 1)
        SendMessage(hwnd,WM_SYSCOMMAND,SC_MINIMIZE,0);
      else if (iEscFunction == 2)
        SendMessage(hwnd,WM_CLOSE,0,0);
      break;


    // Newline with toggled auto indent setting
    case CMD_CTRLENTER:
      bAutoIndent = (bAutoIndent) ? 0 : 1;
      SendMessage(hwndEdit,SCI_NEWLINE,0,0);
      bAutoIndent = (bAutoIndent) ? 0 : 1;
      break;


    case CMD_SHIFTF8:
      {
        char tchCurFile2[MAX_PATH];
        if (lstrlen(szCurFile)) {
          lstrcpy(tchCurFile2,szCurFile);
          FileLoad(FALSE,FALSE,TRUE,TRUE,tchCurFile2); } }
      break;


    case CMD_LEXDEFAULT:
      Style_SetDefaultLexer(hwndEdit);
      UpdateStatusbar();
      UpdateLineNumberWidth();
      break;


    case CMD_LEXHTML:
      Style_SetHTMLLexer(hwndEdit);
      UpdateStatusbar();
      UpdateLineNumberWidth();
      break;


    case CMD_LEXXML:
      Style_SetXMLLexer(hwndEdit);
      UpdateStatusbar();
      UpdateLineNumberWidth();
      break;


    case CMD_WEBACTION1:
    case CMD_WEBACTION2:
      {
        HKEY  hKey;
        BOOL  bCmdEnabled = FALSE;
        LPSTR lpszTemplateName;
        char  szCmdTemplate[256];
        LPSTR lpszSelection;
        DWORD cchSelection;
        LPSTR lpsz;
        LPSTR lpszCommand;
        LPSTR lpszArgs;
        SHELLEXECUTEINFO sei;

        lpszTemplateName = (LOWORD(wParam) == CMD_WEBACTION1) ? "WebTemplate1" : "WebTemplate2";

        hKey = RegGetAppKey("Settings");
        bCmdEnabled = RegGetString(hKey,lpszTemplateName,"",szCmdTemplate,COUNTOF(szCmdTemplate));
        RegCloseKey(hKey);

        if (bCmdEnabled) {

          cchSelection = SendMessage(hwndEdit,SCI_GETSELECTIONEND,0,0) -
                          SendMessage(hwndEdit,SCI_GETSELECTIONSTART,0,0);

          if (cchSelection > 0 && cchSelection < 256)
          {
            lpszSelection = GlobalAlloc(GPTR,cchSelection+2);
            SendMessage(hwndEdit,SCI_GETSELTEXT,0,(LPARAM)lpszSelection);

            // Check lpszSelection and truncate bad chars
            lpsz = strchr(lpszSelection,13);
            if (lpsz) *lpsz = '\0';

            lpsz = strchr(lpszSelection,10);
            if (lpsz) *lpsz = '\0';

            lpsz = strchr(lpszSelection,9);
            if (lpsz) *lpsz = '\0';

            if (lstrlen(lpszSelection)) {

              lpszCommand = GlobalAlloc(GPTR,GlobalSize(lpszSelection)+COUNTOF(szCmdTemplate)+MAX_PATH+32);
              wsprintf(lpszCommand,szCmdTemplate,lpszSelection);
              ExpandEnvironmentStringsEx(lpszCommand,GlobalSize(lpszCommand));

              lpszArgs = GlobalAlloc(GPTR,GlobalSize(lpszCommand));
              ExtractFirstArgument(lpszCommand,lpszCommand,lpszArgs);

              ZeroMemory(&sei,sizeof(SHELLEXECUTEINFO));

              sei.cbSize = sizeof(SHELLEXECUTEINFO);
              sei.fMask = SEE_MASK_NOCLOSEPROCESS;
              sei.hwnd = NULL;
              sei.lpVerb = NULL;
              sei.lpFile = lpszCommand;
              sei.lpParameters = lpszArgs;
              sei.lpDirectory = NULL;
              sei.nShow = SW_SHOWNORMAL;

              ShellExecuteEx(&sei);

              GlobalFree(lpszSelection);
              GlobalFree(lpszCommand);
            }
          }
        }
      }
      break;


    case IDT_FILE_NEW:
      if (IsCmdEnabled(hwnd,IDM_FILE_NEW))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_NEW,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_FILE_OPEN:
      if (IsCmdEnabled(hwnd,IDM_FILE_OPEN))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_OPEN,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_FILE_METAPATH:
      if (IsCmdEnabled(hwnd,IDM_FILE_METAPATH))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_METAPATH,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_FILE_SAVE:
      if (IsCmdEnabled(hwnd,IDM_FILE_SAVE))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_SAVE,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_UNDO:
      if (IsCmdEnabled(hwnd,IDM_EDIT_UNDO))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_UNDO,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_REDO:
      if (IsCmdEnabled(hwnd,IDM_EDIT_REDO))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_REDO,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_CUT:
      if (IsCmdEnabled(hwnd,IDM_EDIT_CUT))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_CUT,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_COPY:
      if (IsCmdEnabled(hwnd,IDM_EDIT_COPY))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_COPY,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_PASTE:
      if (IsCmdEnabled(hwnd,IDM_EDIT_PASTE))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_PASTE,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_FIND:
      if (IsCmdEnabled(hwnd,IDM_EDIT_FIND))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_FIND,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_REPLACE:
      if (IsCmdEnabled(hwnd,IDM_EDIT_REPLACE))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_REPLACE,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_VIEW_WORDWRAP:
      if (IsCmdEnabled(hwnd,IDM_VIEW_WORDWRAP))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_VIEW_WORDWRAP,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_VIEW_ZOOMIN:
      if (IsCmdEnabled(hwnd,IDM_VIEW_ZOOMIN))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_VIEW_ZOOMIN,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_VIEW_ZOOMOUT:
      if (IsCmdEnabled(hwnd,IDM_VIEW_ZOOMOUT))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_VIEW_ZOOMOUT,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_VIEW_SCHEME:
      if (IsCmdEnabled(hwnd,IDM_VIEW_SCHEME))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_VIEW_SCHEME,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_VIEW_SCHEMECONFIG:
      if (IsCmdEnabled(hwnd,IDM_VIEW_SCHEMECONFIG))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_VIEW_SCHEMECONFIG,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_FILE_EXIT:
      SendMessage(hwnd,WM_CLOSE,0,0);
      break;


    case IDT_FILE_SAVEAS:
      if (IsCmdEnabled(hwnd,IDM_FILE_SAVEAS))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_SAVEAS,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_FILE_SAVECOPY:
      if (IsCmdEnabled(hwnd,IDM_FILE_SAVECOPY))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_SAVECOPY,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_COPYALL:
      if (IsCmdEnabled(hwnd,IDM_EDIT_COPYALL))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_COPYALL,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_CLEAR:
      if (IsCmdEnabled(hwnd,IDM_EDIT_CLEAR))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_CLEAR,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_EDIT_FINDNEXT:
      if (IsCmdEnabled(hwnd,IDM_EDIT_FINDNEXT))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_FINDNEXT,1),0);
      else
        MessageBeep(0);
      break;



    case IDT_EDIT_FINDPREV:
      if (IsCmdEnabled(hwnd,IDM_EDIT_FINDPREV))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_FINDPREV,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_FILE_PRINT:
      if (IsCmdEnabled(hwnd,IDM_FILE_PRINT))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_PRINT,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_FILE_OPENFAV:
      if (IsCmdEnabled(hwnd,IDM_FILE_OPENFAV))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_OPENFAV,1),0);
      else
        MessageBeep(0);
      break;


    case IDT_FILE_ADDTOFAV:
      if (IsCmdEnabled(hwnd,IDM_FILE_ADDTOFAV))
        SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_FILE_ADDTOFAV,1),0);
      else
        MessageBeep(0);
      break;

  }

  return(0);

}


//=============================================================================
//
//  MsgNotify() - Handles WM_NOTIFY
//
//
LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam)
{

  LPNMHDR pnmh = (LPNMHDR)lParam;
  struct SCNotification* scn = (struct SCNotification*)lParam;

  switch(pnmh->idFrom)
  {

    case IDC_EDIT:

      switch(pnmh->code)
      {
        case SCN_UPDATEUI:
          UpdateToolbar();
          UpdateStatusbar();

          // Brace Match
          if (bMatchBraces)
          {
            int iPos = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
            char c = (char)SendMessage(hwndEdit,SCI_GETCHARAT,iPos,0);
            if (StrChr("()[]{}",c)) {
              int iBrace2 = SendMessage(hwndEdit,SCI_BRACEMATCH,iPos,0);
              if (iBrace2 != -1)
                SendMessage(hwndEdit,SCI_BRACEHIGHLIGHT,iPos,iBrace2);
              else
                SendMessage(hwndEdit,SCI_BRACEBADLIGHT,iPos,0);
            }
            // Try one before
            else
            {
              iPos = SendMessage(hwndEdit,SCI_POSITIONBEFORE,iPos,0);
              c = (char)SendMessage(hwndEdit,SCI_GETCHARAT,iPos,0);
              if (StrChr("()[]{}",c)) {
                int iBrace2 = SendMessage(hwndEdit,SCI_BRACEMATCH,iPos,0);
                if (iBrace2 != -1)
                  SendMessage(hwndEdit,SCI_BRACEHIGHLIGHT,iPos,iBrace2);
                else
                  SendMessage(hwndEdit,SCI_BRACEBADLIGHT,iPos,0);
              }
              else
                SendMessage(hwndEdit,SCI_BRACEHIGHLIGHT,(WPARAM)-1,(LPARAM)-1);
            }
          }
          break;

        case SCN_CHARADDED:
          // Auto indent
          if (bAutoIndent && (scn->ch == '\x0D' || scn->ch == '\x0A'))
          {
            // in CRLF mode handle LF only...
            if ((SC_EOL_CRLF == iEOLMode && scn->ch != '\x0A') || SC_EOL_CRLF != iEOLMode)
            {
              char *pLineBuf;
              char *pPos;
              //int  iIndentLen;

              int iCurPos    = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
              //int iAnchorPos = SendMessage(hwndEdit,SCI_GETANCHOR,0,0);
              int iCurLine = SendMessage(hwndEdit,SCI_LINEFROMPOSITION,(WPARAM)iCurPos,0);
              int iLineLength = SendMessage(hwndEdit,SCI_LINELENGTH,iCurLine,0);
              //int iIndentBefore = SendMessage(hwndEdit,SCI_GETLINEINDENTATION,(WPARAM)iCurLine-1,0);

              if (iCurLine > 0/* && iLineLength <= 2*/)
              {
                int iPrevLineLength = SendMessage(hwndEdit,SCI_LINELENGTH,iCurLine-1,0);
                if (pLineBuf = GlobalAlloc(GPTR,iPrevLineLength+1))
                {
                  SendMessage(hwndEdit,SCI_GETLINE,iCurLine-1,(LPARAM)pLineBuf);
                  *(pLineBuf+iPrevLineLength) = '\0';
                  for (pPos = pLineBuf; *pPos; pPos++) {
                    if (*pPos != ' ' && *pPos != '\t')
                      *pPos = '\0'; }
                  if (*pLineBuf) {
                    SendMessage(hwndEdit,SCI_BEGINUNDOACTION,0,0);
                    SendMessage(hwndEdit,SCI_ADDTEXT,lstrlen(pLineBuf),(LPARAM)pLineBuf);
                    SendMessage(hwndEdit,SCI_ENDUNDOACTION,0,0); }
                  GlobalFree(pLineBuf);
                  //int iIndent = SendMessage(hwndEdit,SCI_GETLINEINDENTATION,(WPARAM)iCurLine,0);
                  //SendMessage(hwndEdit,SCI_SETLINEINDENTATION,(WPARAM)iCurLine,(LPARAM)iIndentBefore);
                  //iIndentLen = /*- iIndent +*/ SendMessage(hwndEdit,SCI_GETLINEINDENTATION,(WPARAM)iCurLine,0);
                  //if (iIndentLen > 0)
                  //  SendMessage(hwndEdit,SCI_SETSEL,(WPARAM)iAnchorPos+iIndentLen,(LPARAM)iCurPos+iIndentLen);
                }
              }
            }
          }
          // Auto close tags
          else if (bAutoCloseTags && scn->ch == '>')
          {
            int iLexer = SendMessage(hwndEdit,SCI_GETLEXER,0,0);
            if (iLexer == SCLEX_HTML || iLexer == SCLEX_XML)
            {
              char tchBuf[512];
              char tchIns[516] = "</";
              int  cchIns = 2;
              int  iCurPos = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);
              int  iHelper = iCurPos - (COUNTOF(tchBuf) - 1);
              int  iStartPos = max(0,iHelper);
              int  iSize = iCurPos - iStartPos;

              if (iSize >= 3) {

                struct TextRange tr = { { iStartPos, iCurPos }, tchBuf };
                SendMessage(hwndEdit,SCI_GETTEXTRANGE,0,(LPARAM)&tr);

                if (tchBuf[iSize - 2] != '/') {

                  const char* pBegin = &tchBuf[0];
                  const char* pCur = &tchBuf[iSize - 2];

                  while (pCur > pBegin && *pCur != '<' && *pCur != '>')
                    --pCur;

                  if (*pCur == '<') {
                    pCur++;
                    while (StrChr(":_-.", *pCur) || IsCharAlphaNumeric(*pCur)) {
                      tchIns[cchIns++] = *pCur;
                      pCur++;
                    }
                  }

                  tchIns[cchIns++] = '>';
                  tchIns[cchIns] = 0;

                  if (cchIns > 3)
                  {
                    SendMessage(hwndEdit,SCI_BEGINUNDOACTION,0,0);
                    SendMessage(hwndEdit,SCI_REPLACESEL,0,(LPARAM)tchIns);
                    SendMessage(hwndEdit,SCI_SETSEL,iCurPos,iCurPos);
                    SendMessage(hwndEdit,SCI_ENDUNDOACTION,0,0);
                  }
                }
              }
            }
          }
          break;

        case SCN_MODIFIED:
        case SCN_ZOOM:
          UpdateLineNumberWidth();
          break;

        case SCN_SAVEPOINTREACHED:
          bModified = FALSE;
          SetWindowTitle(hwnd,uidsAppTitle,IDS_UNTITLED,szCurFile,
            bShortPathNames,bModified || iCodePage != iInitialCP,
            IDS_READONLY,bReadOnly);
          break;

        case SCN_SAVEPOINTLEFT:
          bModified = TRUE;
          SetWindowTitle(hwnd,uidsAppTitle,IDS_UNTITLED,szCurFile,
            bShortPathNames,bModified || iCodePage != iInitialCP,
            IDS_READONLY,bReadOnly);
          break;
      }
      break;


    case IDC_TOOLBAR:

      switch(pnmh->code)
      {

        case TBN_ENDADJUST:
          UpdateToolbar();
          break;

        case TBN_QUERYDELETE:
        case TBN_QUERYINSERT:
          return TRUE;

        case TBN_GETBUTTONINFO:
          {
            if (((LPTBNOTIFY)lParam)->iItem < COUNTOF(tbbMainWnd))
            {
              char tch[256];
              GetString(tbbMainWnd[((LPTBNOTIFY)lParam)->iItem].idCommand,tch,COUNTOF(tch));
              lstrcpyn(((LPTBNOTIFY)lParam)->pszText,/*strchr(tch,'\n')+1*/tch,((LPTBNOTIFY)lParam)->cchText);
              CopyMemory(&((LPTBNOTIFY)lParam)->tbButton,&tbbMainWnd[((LPTBNOTIFY)lParam)->iItem],sizeof(TBBUTTON));
              return TRUE;
            }
          }
          return FALSE;

        case TBN_RESET:
          {
            int i; int c = SendMessage(hwndToolbar,TB_BUTTONCOUNT,0,0);
            for (i = 0; i < c; i++)
              SendMessage(hwndToolbar,TB_DELETEBUTTON,0,0);
            SendMessage(hwndToolbar,TB_ADDBUTTONS,NUMINITIALTOOLS,(LPARAM)tbbMainWnd);
            return(0);
          }

      }
      break;


    case IDC_STATUSBAR:

      switch(pnmh->code)
      {

        case NM_DBLCLK:
          {
            int i;
            LPNMMOUSE pnmm = (LPNMMOUSE)lParam;

            switch (pnmm->dwItemSpec)
            {
              case STATUS_CODEPAGE:
                if (iCodePage & NCP_UNICODE_REVERSE)
                  i = IDM_ENCODING_UNICODEREV;
                else if (iCodePage & NCP_UNICODE)
                  i = IDM_ENCODING_UNICODE;
                else if (iCodePage & NCP_UTF8_SIGN)
                  i = IDM_ENCODING_UTF8SIGN;
                else if (iCodePage & NCP_UTF8)
                  i = IDM_ENCODING_UTF8;
                else
                  i = IDM_ENCODING_ANSI;
                i++;
                if (i > IDM_ENCODING_UTF8SIGN)
                  i = IDM_ENCODING_ANSI;
                SendMessage(hwnd,WM_COMMAND,MAKELONG(i,1),0);
                return TRUE;

              case STATUS_EOLMODE:
                if (iEOLMode == SC_EOL_CRLF)
                  i = IDM_LINEENDINGS_CRLF;
                else if (iEOLMode == SC_EOL_LF)
                  i = IDM_LINEENDINGS_LF;
                else
                  i = IDM_LINEENDINGS_CR;
                i++;
                if (i > IDM_LINEENDINGS_CR)
                  i = IDM_LINEENDINGS_CRLF;
                SendMessage(hwnd,WM_COMMAND,MAKELONG(i,1),0);
                return TRUE;

              case STATUS_LEXER:
                SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_VIEW_SCHEME,1),0);
                return TRUE;

              case STATUS_OVRMODE:
                SendMessage(hwndEdit,SCI_EDITTOGGLEOVERTYPE,0,0);
                return TRUE;

              default:
                return FALSE;
            }
          }
          break;

      }
      break;


    default:

      switch(pnmh->code)
      {

        case TTN_NEEDTEXT:
          {
            char tch[256];

            if (((LPTOOLTIPTEXT)lParam)->uFlags == TTF_IDISHWND)
            {
/*            if (fTitleToolTip)
              {
                PathCompactPathEx(((LPTOOLTIPTEXT)lParam)->szText,szCurDir,
                                  COUNTOF(((LPTOOLTIPTEXT)lParam)->szText),0);
              }*/
            }

            else
            {
              GetString(pnmh->idFrom,tch,COUNTOF(tch));
              lstrcpyn(((LPTOOLTIPTEXT)lParam)->szText,/*strchr(tch,'\n')+1*/tch,80);
            }
          }
          break;

      }
      break;

  }


  return(0);

}


//=============================================================================
//
//  LoadSettings()
//
//
void LoadSettings()
{

  HKEY hKey;

  hKey = RegGetAppKey("Settings");

  bSaveSettings =
    RegGetInt(hKey,"SaveSettings",1);
  if (bSaveSettings) bSaveSettings = 1;

  bSaveRecentFiles =
    RegGetInt(hKey,"SaveRecentFiles",0);
  if (bSaveRecentFiles) bSaveRecentFiles = 1;

  bSaveFindReplace =
    RegGetInt(hKey,"SaveFindReplace",0);
  if (bSaveFindReplace) bSaveFindReplace = 1;

  efrData.bFindClose = RegGetInt(hKey,"CloseFind",1);
  if (efrData.bFindClose) efrData.bReplaceClose = TRUE;

  efrData.bReplaceClose = RegGetInt(hKey,"CloseReplace",1);
  if (efrData.bReplaceClose) efrData.bReplaceClose = TRUE;

  if (!RegGetString(hKey,"OpenWithDir","",
        tchOpenWithDir,COUNTOF(tchOpenWithDir)))
    GetDefaultOpenWithDir(tchOpenWithDir,COUNTOF(tchOpenWithDir));

  if (!RegGetString(hKey,"Favorites","",
        tchFavoritesDir,COUNTOF(tchFavoritesDir)))
    GetDefaultFavoritesDir(tchFavoritesDir,COUNTOF(tchFavoritesDir));

  RegGetString(hKey,"DefaultExtension","txt",
    tchDefaultExtension,COUNTOF(tchDefaultExtension));

  RegGetString(hKey,"ToolbarBitmap","",
    tchToolbarBitmap,COUNTOF(tchToolbarBitmap));
  RegGetString(hKey,"ToolbarBitmapHot","",
    tchToolbarBitmapHot,COUNTOF(tchToolbarBitmap));
  RegGetString(hKey,"ToolbarBitmapDisabled","",
    tchToolbarBitmapDisabled,COUNTOF(tchToolbarBitmap));

  bShortPathNames = RegGetInt(hKey,"ShortPathNames",0);
  if (bShortPathNames) bShortPathNames = 1;

  fWordWrap = RegGetInt(hKey,"WordWrap",0);
  if (fWordWrap) fWordWrap = 1;

  iWordWrapIndent = RegGetInt(hKey,"WordWrapIndent",0);
  iWordWrapIndent = max(min(iWordWrapIndent,1024),0);

  iWordWrapSymbols = RegGetInt(hKey,"WordWrapSymbols",0);
  iWordWrapSymbols = max(min(iWordWrapSymbols,3),0);

  bShowWordWrapSymbols = RegGetInt(hKey,"ShowWordWrapSymbols",0);
  if (bShowWordWrapSymbols) bShowWordWrapSymbols = 1;

  bMatchBraces = RegGetInt(hKey,"MatchBraces",1);
  if (bMatchBraces) bMatchBraces = 1;

  bAutoIndent = RegGetInt(hKey,"AutoIndent",1);
  if (bAutoIndent) bAutoIndent = 1;

  bAutoCloseTags = RegGetInt(hKey,"AutoCloseTags",0);
  if (bAutoCloseTags) bAutoCloseTags = 1;

  bShowIndentGuides = RegGetInt(hKey,"ShowIndentGuides",0);
  if (bShowIndentGuides) bShowIndentGuides = 1;

  bTabsAsSpaces = RegGetInt(hKey,"TabsAsSpaces",0);
  if (bTabsAsSpaces) bTabsAsSpaces = 1;

  iTabWidth = RegGetInt(hKey,"TabWidth",4);
  iTabWidth = max(min(iTabWidth,24),1);

  bMarkLongLines = RegGetInt(hKey,"MarkLongLines",0);
  if (bMarkLongLines) bMarkLongLines = 1;

  iLongLinesLimit = RegGetInt(hKey,"LongLinesLimit",72);
  iLongLinesLimit = max(min(iLongLinesLimit,1024),0);

  iLongLineMode = RegGetInt(hKey,"LongLineMode",EDGE_LINE);
  iLongLineMode = max(min(iLongLineMode,EDGE_BACKGROUND),EDGE_LINE);

  bShowSelectionMargin = RegGetInt(hKey,"ShowSelectionMargin",1);
  if (bShowSelectionMargin) bShowSelectionMargin = 1;

  bShowLineNumbers = RegGetInt(hKey,"ShowLineNumbers",0);
  if (bShowLineNumbers) bShowLineNumbers = 1;

  bViewWhiteSpace = RegGetInt(hKey,"ViewWhiteSpace",0);
  if (bViewWhiteSpace) bViewWhiteSpace = 1;

  bViewEOLs = RegGetInt(hKey,"ViewEOLs",0);
  if (bViewEOLs) bViewEOLs = 1;

  iDefaultEncoding = RegGetInt(hKey,"DefaultEncoding",0);
  iDefaultEncoding = max(min(iDefaultEncoding,4),0);

  iDefaultEOLMode = RegGetInt(hKey,"DefaultEOLMode",0);
  iDefaultEOLMode = max(min(iDefaultEOLMode,2),0);

  iPrintHeader = RegGetInt(hKey,"PrintHeader",1);
  iPrintHeader = max(min(iPrintHeader,3),0);

  iPrintFooter = RegGetInt(hKey,"PrintFooter",0);
  iPrintFooter = max(min(iPrintFooter,1),0);

  iPrintZoom = RegGetInt(hKey,"PrintZoom",10)-10;
  iPrintZoom = max(min(iPrintZoom,20),-10);

  pagesetupMargin.left = RegGetInt(hKey,"PrintMarginLeft",0);
  pagesetupMargin.left = max(pagesetupMargin.left,0);

  pagesetupMargin.top = RegGetInt(hKey,"PrintMarginTop",0);
  pagesetupMargin.top = max(pagesetupMargin.top,0);

  pagesetupMargin.right = RegGetInt(hKey,"PrintMarginRight",0);
  pagesetupMargin.right = max(pagesetupMargin.right,0);

  pagesetupMargin.bottom = RegGetInt(hKey,"PrintMarginBottom",0);
  pagesetupMargin.bottom = max(pagesetupMargin.bottom,0);

  bSaveBeforeRunningTools = RegGetInt(hKey,"SaveBeforeRunningTools",0);
  if (bSaveBeforeRunningTools) bSaveBeforeRunningTools = 1;

  //bEnableFileWatching = RegGetInt(hKey,"EnableFileWatching",0);
  //if (bEnableFileWatching) bEnableFileWatching = 1;

  iEscFunction = RegGetInt(hKey,"EscFunction",0);
  iEscFunction = max(min(iEscFunction,2),0);

  bAlwaysOnTop = RegGetInt(hKey,"AlwaysOnTop",0);
  if (bAlwaysOnTop) bAlwaysOnTop = 1;

  bMinimizeToTray = RegGetInt(hKey,"MinimizeToTray",0);
  if (bMinimizeToTray) bMinimizeToTray = 1;

  bTransparentMode = RegGetInt(hKey,"TransparentMode",0);
  if (bTransparentMode) bTransparentMode = 1;

  // Check if SetLayeredWindowAttributes() is available
  bTransparentModeAvailable =
    (GetProcAddress(GetModuleHandle("User32"),"SetLayeredWindowAttributes") != NULL);

  bShowToolbar = RegGetInt(hKey,"ShowToolbar",1);
  if (bShowToolbar) bShowToolbar = 1;

  bShowStatusbar = RegGetInt(hKey,"ShowStatusbar",1);
  if (bShowStatusbar) bShowStatusbar = 1;

  cxFileMRUDlg = RegGetInt(hKey,"FileMRUDlgSizeX",0);
  cxFileMRUDlg = max(cxFileMRUDlg,0);

  cyFileMRUDlg = RegGetInt(hKey,"FileMRUDlgSizeY",0);
  cyFileMRUDlg = max(cyFileMRUDlg,0);

  cxOpenWithDlg = RegGetInt(hKey,"OpenWithDlgSizeX",0);
  cxOpenWithDlg = max(cxOpenWithDlg,0);

  cyOpenWithDlg = RegGetInt(hKey,"OpenWithDlgSizeY",0);
  cyOpenWithDlg = max(cyOpenWithDlg,0);

  cxFavoritesDlg = RegGetInt(hKey,"FavoritesDlgSizeX",0);
  cxFavoritesDlg = max(cxFavoritesDlg,0);

  cyFavoritesDlg = RegGetInt(hKey,"FavoritesDlgSizeY",0);
  cyFavoritesDlg = max(cyFavoritesDlg,0);

  RegCloseKey(hKey);

  hKey = RegGetAppKey("Window");

  if (!flagPosParam) { // ignore window position if /p was specified
    wi.x = RegGetInt(hKey,"PosX",CW_USEDEFAULT);
    wi.y = RegGetInt(hKey,"PosY",CW_USEDEFAULT);
    wi.cx = RegGetInt(hKey,"SizeX",CW_USEDEFAULT);
    wi.cy = RegGetInt(hKey,"SizeY",CW_USEDEFAULT);
    wi.max = RegGetInt(hKey,"Maximized",0);
    if (wi.max) wi.max = 1; }

  RegCloseKey(hKey);

  // Codepage and Character Set
  hKey = RegGetAppKey("International");
  iDefaultCodePage = RegGetInt(hKey,"CodePage",GetACP()/* default */);
  iDefaultCharSet  = RegGetInt(hKey,"CharSet",DEFAULT_CHARSET);
  bAutoSelACP = RegGetInt(hKey,"AutoSelACP",0) ? 1 : 0;
  RegCloseKey(hKey);

  // Check default charset
  if (bAutoSelACP)
    iDefaultCodePage = CodePageFromCharSet(iDefaultCharSet);

  // Scintilla Styles
  hKey = RegGetAppKey("Styles");
  Style_Load(hKey);
  RegCloseKey(hKey);

}


//=============================================================================
//
//  SaveSettings()
//
//
void SaveSettings(BOOL bSaveSettingsNow)
{

  HKEY hKey;
  TBSAVEPARAMS tbsp = { HKEY_CURRENT_USER, "Software\\Notepad2\\Toolbar", "Settings" };

  hKey = RegGetAppKey("Settings");
  RegSetInt(hKey,"SaveSettings",bSaveSettings);
  RegCloseKey(hKey);

  if (!bSaveSettings && !bSaveSettingsNow)
    return;

  // Save Toolbar configuration
  // hwndToolbar must be valid here!
  SendMessage(hwndToolbar,TB_SAVERESTORE,TRUE,(LPARAM)&tbsp);

  hKey = RegGetAppKey("Settings");

  RegSetInt(hKey,"SaveRecentFiles",bSaveRecentFiles);
  RegSetInt(hKey,"SaveFindReplace",bSaveFindReplace);
  RegSetInt(hKey,"CloseFind",efrData.bFindClose);
  RegSetInt(hKey,"CloseReplace",efrData.bReplaceClose);
  RegSetString(hKey,"OpenWithDir",tchOpenWithDir);
  RegSetString(hKey,"Favorites",tchFavoritesDir);
  //RegSetString(hKey,"DefaultExtension",tchDefaultExtension);
  RegSetInt(hKey,"ShortPathNames",bShortPathNames);
  RegSetInt(hKey,"WordWrap",fWordWrap);
  RegSetInt(hKey,"WordWrapIndent",iWordWrapIndent);
  RegSetInt(hKey,"WordWrapSymbols",iWordWrapSymbols);
  RegSetInt(hKey,"ShowWordWrapSymbols",bShowWordWrapSymbols);
  RegSetInt(hKey,"MatchBraces",bMatchBraces);
  RegSetInt(hKey,"AutoIndent",bAutoIndent);
  RegSetInt(hKey,"AutoCloseTags",bAutoCloseTags);
  RegSetInt(hKey,"ShowIndentGuides",bShowIndentGuides);
  RegSetInt(hKey,"TabsAsSpaces",bTabsAsSpaces);
  RegSetInt(hKey,"TabWidth",iTabWidth);
  RegSetInt(hKey,"MarkLongLines",bMarkLongLines);
  RegSetInt(hKey,"LongLinesLimit",iLongLinesLimit);
  RegSetInt(hKey,"LongLineMode",iLongLineMode);
  RegSetInt(hKey,"ShowSelectionMargin",bShowSelectionMargin);
  RegSetInt(hKey,"ShowLineNumbers",bShowLineNumbers);
  RegSetInt(hKey,"ViewWhiteSpace",bViewWhiteSpace);
  RegSetInt(hKey,"ViewEOLs",bViewEOLs);
  RegSetInt(hKey,"DefaultEncoding",iDefaultEncoding);
  RegSetInt(hKey,"DefaultEOLMode",iDefaultEOLMode);
  RegSetInt(hKey,"PrintHeader",iPrintHeader);
  RegSetInt(hKey,"PrintFooter",iPrintFooter);
  RegSetInt(hKey,"PrintZoom",iPrintZoom+10);
  RegSetInt(hKey,"PrintMarginLeft",pagesetupMargin.left);
  RegSetInt(hKey,"PrintMarginTop",pagesetupMargin.top);
  RegSetInt(hKey,"PrintMarginRight",pagesetupMargin.right);
  RegSetInt(hKey,"PrintMarginBottom",pagesetupMargin.bottom);
  RegSetInt(hKey,"SaveBeforeRunningTools",bSaveBeforeRunningTools);
  //RegSetInt(hKey,"EnableFileWatching",bEnableFileWatching);
  RegSetInt(hKey,"EscFunction",iEscFunction);
  RegSetInt(hKey,"AlwaysOnTop",bAlwaysOnTop);
  RegSetInt(hKey,"MinimizeToTray",bMinimizeToTray);
  RegSetInt(hKey,"TransparentMode",bTransparentMode);
  RegSetInt(hKey,"ShowToolbar",bShowToolbar);
  RegSetInt(hKey,"ShowStatusbar",bShowStatusbar);
  RegSetInt(hKey,"FileMRUDlgSizeX",cxFileMRUDlg);
  RegSetInt(hKey,"FileMRUDlgSizeY",cyFileMRUDlg);
  RegSetInt(hKey,"OpenWithDlgSizeX",cxOpenWithDlg);
  RegSetInt(hKey,"OpenWithDlgSizeY",cyOpenWithDlg);
  RegSetInt(hKey,"FavoritesDlgSizeX",cxFavoritesDlg);
  RegSetInt(hKey,"FavoritesDlgSizeY",cyFavoritesDlg);

  RegCloseKey(hKey);

  /*
    SaveSettingsNow(): query Window Dimensions
  */

  if (bSaveSettingsNow)
  {
    WINDOWPLACEMENT wndpl;

    // GetWindowPlacement
    wndpl.length = sizeof(WINDOWPLACEMENT);
    GetWindowPlacement(hwndMain,&wndpl);

    wi.x = wndpl.rcNormalPosition.left;
    wi.y = wndpl.rcNormalPosition.top;
    wi.cx = wndpl.rcNormalPosition.right - wndpl.rcNormalPosition.left;
    wi.cy = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top;
    wi.max = (IsZoomed(hwndMain) || (wndpl.flags & WPF_RESTORETOMAXIMIZED));
  }

  hKey = RegGetAppKey("Window");

  RegSetInt(hKey,"PosX",wi.x);
  RegSetInt(hKey,"PosY",wi.y);
  RegSetInt(hKey,"SizeX",wi.cx);
  RegSetInt(hKey,"SizeY",wi.cy);
  RegSetInt(hKey,"Maximized",wi.max);

  RegCloseKey(hKey);

  // Codepage and Character Set
  hKey = RegGetAppKey("International");
  //RegSetInt(hKey,"CodePage",iDefaultCodePage);
  RegSetInt(hKey,"CharSet",iDefaultCharSet);
  RegSetInt(hKey,"AutoSelACP",bAutoSelACP);
  RegCloseKey(hKey);

  // Scintilla Styles
  hKey = RegGetAppKey("Styles");
  Style_Save(hKey);
  RegCloseKey(hKey);

}


//=============================================================================
//
//  ParseCommandLine()
//
//
void ParseCommandLine(LPSTR lpCmdLine)
{

  HKEY  hKey;
  LPSTR lp1,lp2,lp3;
  BOOL bContinue = TRUE;

  hKey = RegGetAppKey("Settings");

  if (!RegGetInt(hKey,"ReuseWindow2",0))
    flagNoReuseWindow = 1;

  if (RegGetInt(hKey,"NoFadeHidden",0))
    flagNoFadeHidden = 1;

  RegCloseKey(hKey);

  if (lstrlen(lpCmdLine) == 0)
    return;

  // Good old console can also send args separated by Tabs
  StrTab2Space(lpCmdLine);

  lp1 = LocalAlloc(LPTR,lstrlen(lpCmdLine) + 1);
  lp2 = LocalAlloc(LPTR,lstrlen(lpCmdLine) + 1);
  lp3 = LocalAlloc(LPTR,lstrlen(lpCmdLine) + 1);

  lstrcpy(lp3,lpCmdLine);

  while (bContinue && ExtractFirstArgument(lp3,lp1,lp2))
  {

    // options
    if ((*lp1 == '/') || (*lp1 == '-'))
    {

      switch (*CharUpper((lp1+1)))
      {

        case 'N':
          flagNoReuseWindow = 1;
          break;

        case 'I':
          flagStartAsTrayIcon = 1;
          break;

        case 'U':
          flagUnregProgram = 1;
          break;

        case 'P':
          if (ExtractFirstArgument(lp2,lp1,lp2)) {
            int itok =
              sscanf(lp1,"%i,%i,%i,%i,%i",&wi.x,&wi.y,&wi.cx,&wi.cy,&wi.max);
            if (itok == 4 || itok == 5) { // scan successful
              flagPosParam = 1;
              if (wi.cx < 1) wi.cx = CW_USEDEFAULT;
              if (wi.cy < 1) wi.cy = CW_USEDEFAULT;
              if (wi.max) wi.max = 1;
              if (itok == 4) wi.max = 0; } }
          break;

        case 'C':
          flagNewFromClipboard = 1;
          break;

        case 'B':
          flagPasteBoard = 1;
          break;

        case 'G':
          if (ExtractFirstArgument(lp2,lp1,lp2)) {
            int itok =
              sscanf(lp1,"%i,%i",&iInitialLine,&iInitialColumn);
            if (itok == 1 || itok == 2) { // scan successful
              flagJumpTo = 1; } }
          break;

        case '?':
          flagDisplayHelp = 1;
          break;

        default:
          break;

      }

    }

    // pathname
    else
    {
      if (lpFileArg)
        GlobalFree(lpFileArg);

      lpFileArg = GlobalAlloc(GPTR,MAX_PATH+2); // changed for ActivatePrevInst() needs
      lstrcpy(lpFileArg,lp3);

      TrimString(lpFileArg);
      PathUnquoteSpaces(lpFileArg);

      // only one quote, adjust blanks ...
      if (*lpFileArg == '\"') {
        *lpFileArg = ' ';
        TrimString(lpFileArg); }

      bContinue = FALSE;
    }

    // Continue with next argument
    if (bContinue)
      lstrcpy(lp3,lp2);

  }

  LocalFree(lp1);
  LocalFree(lp2);
  LocalFree(lp3);

}


//=============================================================================
//
//  UpdateToolbar()
//
//
#define EnableTool(id,b) SendMessage(hwndToolbar,TB_ENABLEBUTTON,id, \
                           MAKELONG(((b) ? 1 : 0), 0))

#define CheckTool(id,b)  SendMessage(hwndToolbar,TB_CHECKBUTTON,id, \
                           MAKELONG(b,0))

void UpdateToolbar()
{

  int i;

  if (!bShowToolbar)
    return;

  EnableTool(IDT_FILE_ADDTOFAV,lstrlen(szCurFile));

  EnableTool(IDT_EDIT_UNDO,SendMessage(hwndEdit,SCI_CANUNDO,0,0) /*&& !bReadOnly*/);
  EnableTool(IDT_EDIT_REDO,SendMessage(hwndEdit,SCI_CANREDO,0,0) /*&& !bReadOnly*/);

  i = SendMessage(hwndEdit,SCI_GETSELECTIONEND,0,0) - SendMessage(hwndEdit,SCI_GETSELECTIONSTART,0,0);
  EnableTool(IDT_EDIT_CUT,i /*&& !bReadOnly*/);
  EnableTool(IDT_EDIT_COPY,i /*&& !bReadOnly*/);

  EnableTool(IDT_EDIT_COPYALL,SendMessage(hwndEdit,SCI_GETLENGTH,0,0) /*&& !bReadOnly*/);
  EnableTool(IDT_EDIT_PASTE,SendMessage(hwndEdit,SCI_CANPASTE,0,0) /*&& !bReadOnly*/);
  EnableTool(IDT_EDIT_CLEAR,i /*&& !bReadOnly*/);

  i = SendMessage(hwndEdit,SCI_GETLENGTH,0,0);
  EnableTool(IDT_EDIT_FIND,i);
  EnableTool(IDT_EDIT_FINDNEXT,i);
  EnableTool(IDT_EDIT_FINDPREV,i && lstrlen(efrData.szFind));
  EnableTool(IDT_EDIT_REPLACE,i /*&& !bReadOnly*/);

  CheckTool(IDT_VIEW_WORDWRAP,fWordWrap);

}


//=============================================================================
//
//  UpdateStatusbar()
//
//
void UpdateStatusbar()
{

  int iPos;
  int iLn;
  int iLines;
  int iCol;
  int iSel;
  char tchLn[32];
  char tchLines[32];
  char tchCol[32];
  char tchSel[32];
  char tchDocPos[256];

  int iBytes;
  char tchBytes[64];
  char tchDocSize[256];

  char tchCodePage[32];
  char tchEOLMode[32];

  char tchOvrMode[32];

  if (!bShowStatusbar)
    return;

  iPos = SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0);

  iLn = SendMessage(hwndEdit,SCI_LINEFROMPOSITION,iPos,0) + 1;
  wsprintf(tchLn,"%i",iLn);
  FormatNumberStr(tchLn);

  iLines = SendMessage(hwndEdit,SCI_GETLINECOUNT,0,0);
  wsprintf(tchLines,"%i",iLines);
  FormatNumberStr(tchLines);

  iCol = SendMessage(hwndEdit,SCI_GETCOLUMN,iPos,0) + 1;
  wsprintf(tchCol,"%i",iCol);
  FormatNumberStr(tchCol);

  if (SC_SEL_RECTANGLE != SendMessage(hwndEdit,SCI_GETSELECTIONMODE,0,0))
  {
    iSel = SendMessage(hwndEdit,SCI_GETSELECTIONEND,0,0) - SendMessage(hwndEdit,SCI_GETSELECTIONSTART,0,0);
    wsprintf(tchSel,"%i",iSel);
    FormatNumberStr(tchSel);
  }
  else
    lstrcpy(tchSel,"--");

  FormatString(tchDocPos,COUNTOF(tchDocPos),IDS_DOCPOS,tchLn,tchLines,tchCol,tchSel);

  iBytes = SendMessage(hwndEdit,SCI_GETLENGTH,0,0);
  FormatBytes(tchBytes,COUNTOF(tchBytes),iBytes);

  FormatString(tchDocSize,COUNTOF(tchDocSize),IDS_DOCSIZE,tchBytes);

  if (iCodePage & NCP_UNICODE)
  {
    lstrcpy(tchCodePage,"Unicode");
    if (iCodePage & NCP_UNICODE_REVERSE)
      lstrcat(tchCodePage," BE");
    if (iCodePage & NCP_UNICODE_BOM)
      lstrcat(tchCodePage," BOM");
  }
  else if (iCodePage & NCP_UTF8)
  {
    lstrcpy(tchCodePage,"UTF-8");
    if (iCodePage & NCP_UTF8_SIGN)
      lstrcat(tchCodePage," Signature");
  }
  else
    lstrcpy(tchCodePage,"ANSI");

  if (iEOLMode == SC_EOL_CR)
    lstrcpy(tchEOLMode,"CR");
  else if (iEOLMode == SC_EOL_LF)
    lstrcpy(tchEOLMode,"LF");
  else
    lstrcpy(tchEOLMode,"CR+LF");

  if (SendMessage(hwndEdit,SCI_GETOVERTYPE,0,0))
    lstrcpy(tchOvrMode,"OVR");
  else
    lstrcpy(tchOvrMode,"INS");

  StatusSetText(hwndStatus,STATUS_DOCPOS,tchDocPos);
  StatusSetText(hwndStatus,STATUS_DOCSIZE,tchDocSize);
  StatusSetText(hwndStatus,STATUS_CODEPAGE,tchCodePage);
  StatusSetText(hwndStatus,STATUS_EOLMODE,tchEOLMode);
  StatusSetText(hwndStatus,STATUS_OVRMODE,tchOvrMode);
  StatusSetText(hwndStatus,STATUS_LEXER,Style_GetCurrentLexerName());

  //InvalidateRect(hwndStatus,NULL,TRUE);

}


//=============================================================================
//
//  UpdateLineNumberWidth()
//
//
void UpdateLineNumberWidth()
{
  char tchLines[32];
  int  iLineMarginWidthNow;
  int  iLineMarginWidthFit;

  if (bShowLineNumbers) {

    wsprintf(tchLines,"_%i_",SendMessage(hwndEdit,SCI_GETLINECOUNT,0,0));

    iLineMarginWidthNow = SendMessage(hwndEdit,SCI_GETMARGINWIDTHN,0,0);
    iLineMarginWidthFit = SendMessage(hwndEdit,SCI_TEXTWIDTH,STYLE_LINENUMBER,(LPARAM)tchLines);

    if (iLineMarginWidthNow != iLineMarginWidthFit) {
      //SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,0,0);
      SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,0,iLineMarginWidthFit); }
  }

  else
    SendMessage(hwndEdit,SCI_SETMARGINWIDTHN,0,0);
}


//=============================================================================
//
//  FileIO()
//
//
BOOL FileIO(BOOL fLoad,LPCSTR psz,BOOL bNoEncDetect,int *icp, int *ieol,
            BOOL *pbUnicodeErr,BOOL *pbFileTooBig,BOOL bSaveCopy)
{
  SHFILEINFO shfi;
  char tch[MAX_PATH+40];
  BOOL fSuccess;
  DWORD dwFileAttributes;

  BeginWaitCursor();

  SHGetFileInfo2(psz,0,&shfi,sizeof(SHFILEINFO),SHGFI_DISPLAYNAME);
  FormatString(tch,COUNTOF(tch),(fLoad) ? IDS_LOADFILE : IDS_SAVEFILE,shfi.szDisplayName);

  StatusSetText(hwndStatus,STATUS_HELP,tch);
  StatusSetSimple(hwndStatus,TRUE);

  InvalidateRect(hwndStatus,NULL,TRUE);
  UpdateWindow(hwndStatus);

  if (fLoad)
    fSuccess = EditLoadFile(hwndEdit,psz,bNoEncDetect,icp,ieol,pbUnicodeErr,pbFileTooBig);
  else
    fSuccess = EditSaveFile(hwndEdit,psz,*icp,bSaveCopy);

  dwFileAttributes = GetFileAttributes(psz);
  bReadOnly = (dwFileAttributes != INVALID_FILE_ATTRIBUTES && dwFileAttributes & FILE_ATTRIBUTE_READONLY);

  StatusSetSimple(hwndStatus,FALSE);

  EndWaitCursor();

  return(fSuccess);
}


//=============================================================================
//
//  FileLoad()
//
//
BOOL FileLoad(BOOL bDontSave,BOOL bNew,BOOL bReload,BOOL bNoEncDetect,LPCSTR lpszFile)
{
  char tch[MAX_PATH];
  char szFileName[MAX_PATH];
  BOOL fSuccess;
  BOOL bUnicodeErr = FALSE;
  BOOL bFileTooBig = FALSE;

  if (!bDontSave)
  {
    if (!FileSave(FALSE,TRUE,FALSE,FALSE))
      return FALSE;
  }

  if (bNew) {
    lstrcpy(szCurFile,"");
    EditSetNewText(hwndEdit,"",0);
    Style_SetLexer(hwndEdit,NULL);
    UpdateLineNumberWidth();
    bModified = FALSE;
    bReadOnly = FALSE;
    iEOLMode = iLineEndings[iDefaultEOLMode];
    SendMessage(hwndEdit,SCI_SETEOLMODE,iLineEndings[iDefaultEOLMode],0);
    iCodePage = iEncodings[iDefaultEncoding];
    iInitialCP = iEncodings[iDefaultEncoding];
    SendMessage(hwndEdit,SCI_SETCODEPAGE,(iDefaultEncoding == 0) ? iDefaultCodePage : SC_CP_UTF8,0);
    EditSetNewText(hwndEdit,"",0);
    SetWindowTitle(hwndMain,uidsAppTitle,IDS_UNTITLED,szCurFile,
      bShortPathNames,bModified || iCodePage != iInitialCP,
      IDS_READONLY,bReadOnly);

    // Terminate file watching
    //InstallFileWatching(NULL);

    return TRUE; }

  if (!lpszFile || lstrlen(lpszFile) == 0) {
    if (!OpenFileDlg(hwndMain,tch,COUNTOF(tch),NULL))
      return FALSE; }

  else
    lstrcpy(tch,lpszFile);

  ExpandEnvironmentStringsEx(tch,COUNTOF(tch));

  if (!SearchPath(NULL,tch,NULL,COUNTOF(szFileName),szFileName,NULL))
  {
    if (PathIsRelative(tch)) {
      GetCurrentDirectory(COUNTOF(szFileName),szFileName);
      PathAppend(szFileName,tch); }
    else
      lstrcpy(szFileName,tch);
  }

  PathCanonicalizeEx(tch);
  GetLongPathNameEx(szFileName,szFileName,COUNTOF(szFileName));

  if (PathIsLnkFile(szFileName))
    PathGetLnkPath(szFileName,szFileName,COUNTOF(szFileName));

  // Ask to create a new file...
  if (!bReload && !PathFileExists(szFileName))
  {
    if (MsgBox(MBYESNO,IDS_ASK_CREATE,szFileName) == IDYES) {
      HANDLE hFile = CreateFile(szFileName,
                      GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
                      NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
      if (fSuccess = (hFile != INVALID_HANDLE_VALUE)) {
        CloseHandle(hFile);
        EditSetNewText(hwndEdit,"",0);
        Style_SetLexer(hwndEdit,NULL);
        iEOLMode = iLineEndings[iDefaultEOLMode];
        SendMessage(hwndEdit,SCI_SETEOLMODE,iLineEndings[iDefaultEOLMode],0);
        iCodePage = iEncodings[iDefaultEncoding];
        iInitialCP = iEncodings[iDefaultEncoding];
        SendMessage(hwndEdit,SCI_SETCODEPAGE,(iDefaultEncoding == 0) ? iDefaultCodePage : SC_CP_UTF8,0);
        bReadOnly = FALSE;
        EditSetNewText(hwndEdit,"",0); }
    }
    else
      return FALSE;
  }

  else
    fSuccess = FileIO(TRUE,szFileName,bNoEncDetect,&iCodePage,&iEOLMode,&bUnicodeErr,&bFileTooBig,FALSE);

  if (fSuccess) {
    lstrcpy(szCurFile,szFileName);
    Style_SetLexerFromFile(hwndEdit,szCurFile);
    UpdateLineNumberWidth();
    iInitialCP = iCodePage;
    bModified = FALSE;
    //bReadOnly = FALSE;
    SendMessage(hwndEdit,SCI_SETEOLMODE,iEOLMode,0);
    AddMRUString(hFileMRU,szFileName);
    SetWindowTitle(hwndMain,uidsAppTitle,IDS_UNTITLED,szFileName,
      bShortPathNames,bModified || iCodePage != iInitialCP,
      IDS_READONLY,bReadOnly);

    // Install watching of the current file
    //InstallFileWatching(szCurFile);

    // Show warning: Unicode file loaded as ANSI
    if (bUnicodeErr)
      MsgBox(MBWARN,IDS_ERR_UNICODE);
  }

  else if (!bFileTooBig)
    MsgBox(MBWARN,IDS_ERR_LOADFILE,szFileName);

  return(fSuccess);
}


//=============================================================================
//
//  FileSave()
//
//
BOOL FileSave(BOOL bSaveAlways,BOOL bAsk,BOOL bSaveAs,BOOL bSaveCopy)
{
  char tchFile[MAX_PATH];
  BOOL fSuccess = FALSE;

  if (!bSaveAlways && !bModified && iCodePage == iInitialCP && !bSaveAs)
    return TRUE;

  if (bAsk)
  {
    // File or "Untitled" ...
    char tch[MAX_PATH];
    if (lstrlen(szCurFile))
      lstrcpy(tch,szCurFile);
    else
      GetString(IDS_UNTITLED,tch,COUNTOF(tch));

    switch (MsgBox(MBYESNOCANCEL,IDS_ASK_SAVE,tch)) {
      case IDCANCEL:
        return FALSE;
      case IDNO:
        return TRUE;
    }
  }

  // Read only...
  if (!bSaveAs && !bSaveCopy && lstrlen(szCurFile))
  {
    DWORD dwFileAttributes = GetFileAttributes(szCurFile);
    if (dwFileAttributes != INVALID_FILE_ATTRIBUTES)
      bReadOnly = (dwFileAttributes & FILE_ATTRIBUTE_READONLY);
    if (bReadOnly) {
      SetWindowTitle(hwndMain,uidsAppTitle,IDS_UNTITLED,szCurFile,
        bShortPathNames,bModified || iCodePage != iInitialCP,
        IDS_READONLY,bReadOnly);
      if (MsgBox(MBYESNOWARN,IDS_READONLY_SAVE,szCurFile) == IDYES)
        bSaveAs = TRUE;
      else
        return FALSE;
    }
  }

  // Save As...
  if (bSaveAs || bSaveCopy || lstrlen(szCurFile) == 0)
  {
    lstrcpy(tchFile,szCurFile);
    if (SaveFileDlg(hwndMain,tchFile,COUNTOF(tchFile)))
    {
      if (fSuccess = FileIO(FALSE,tchFile,FALSE,&iCodePage,&iEOLMode,NULL,NULL,bSaveCopy))
      {
        if (!bSaveCopy)
        {
          lstrcpy(szCurFile,tchFile);
          Style_SetLexerFromFile(hwndEdit,szCurFile);
          UpdateLineNumberWidth();
        }
      }
    }
    else
      return FALSE;
  }

  else
    fSuccess = FileIO(FALSE,szCurFile,FALSE,&iCodePage,&iEOLMode,NULL,NULL,FALSE);

  if (fSuccess)
  {
    if (!bSaveCopy)
    {
      bModified = FALSE;
      iInitialCP = iCodePage;
      AddMRUString(hFileMRU,szCurFile);
      SetWindowTitle(hwndMain,uidsAppTitle,IDS_UNTITLED,szCurFile,
        bShortPathNames,bModified || iCodePage != iInitialCP,
        IDS_READONLY,bReadOnly);

      // Install watching of the current file
      //InstallFileWatching(szCurFile);
    }
  }

  else
  {
    if (lstrlen(szCurFile) != 0)
      lstrcpy(tchFile,szCurFile);

    SetWindowTitle(hwndMain,uidsAppTitle,IDS_UNTITLED,szCurFile,
      bShortPathNames,bModified || iCodePage != iInitialCP,
      IDS_READONLY,bReadOnly);

    MsgBox(MBWARN,IDS_ERR_SAVEFILE,tchFile);
  }

  return(fSuccess);
}


//=============================================================================
//
//  OpenFileDlg()
//
//
BOOL OpenFileDlg(HWND hwnd,LPSTR lpstrFile,int cchFile,LPCSTR lpstrInitialDir)
{
  OPENFILENAME ofn;
  char szFile[MAX_PATH];
  char szFilter[NUMLEXERS*1024];
  char tchInitialDir[MAX_PATH];

  lstrcpy(szFile,"");
  Style_GetOpenDlgFilterStr(szFilter,COUNTOF(szFilter));

  if (!lpstrInitialDir && lstrlen(szCurFile)) {
    lstrcpy(tchInitialDir,szCurFile);
    PathRemoveFileSpec(tchInitialDir); }

  ZeroMemory(&ofn,sizeof(OPENFILENAME));
  ofn.lStructSize = sizeof(OPENFILENAME);
  ofn.hwndOwner = hwnd;
  ofn.lpstrFilter = szFilter;
  ofn.lpstrFile = szFile;
  ofn.lpstrInitialDir = (lpstrInitialDir) ? lpstrInitialDir : tchInitialDir;
  ofn.nMaxFile = COUNTOF(szFile);
  ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | /* OFN_NOCHANGEDIR |*/
            /*OFN_DONTADDTORECENT*/0x02000000 | OFN_PATHMUSTEXIST |
              OFN_SHAREAWARE /*| OFN_NODEREFERENCELINKS*/;
  ofn.lpstrDefExt = (lstrlen(tchDefaultExtension)) ? tchDefaultExtension : NULL;

  if (GetOpenFileName(&ofn)) {
    lstrcpyn(lpstrFile,szFile,cchFile);
    return TRUE; }

  else
    return FALSE;
}


//=============================================================================
//
//  SaveFileDlg()
//
//
BOOL SaveFileDlg(HWND hwnd,LPSTR lpstrFile,int cchFile)
{
  OPENFILENAME ofn;
  char szNewFile[MAX_PATH];
  char szFilter[NUMLEXERS*1024];

  lstrcpy(szNewFile,lpstrFile);
  Style_GetOpenDlgFilterStr(szFilter,COUNTOF(szFilter));

  ZeroMemory(&ofn,sizeof(OPENFILENAME));
  ofn.lStructSize = sizeof(OPENFILENAME);
  ofn.hwndOwner = hwnd;
  ofn.lpstrFilter = szFilter;
  ofn.lpstrFile = szNewFile;
  ofn.nMaxFile = MAX_PATH;
  ofn.Flags = OFN_HIDEREADONLY /*| OFN_NOCHANGEDIR*/ |
            /*OFN_NODEREFERENCELINKS |*/ OFN_OVERWRITEPROMPT |
            /*OFN_DONTADDTORECENT*/0x02000000 | OFN_PATHMUSTEXIST;
  ofn.lpstrDefExt = (lstrlen(tchDefaultExtension)) ? tchDefaultExtension : NULL;

  if (GetSaveFileName(&ofn)) {
    lstrcpyn(lpstrFile,szNewFile,cchFile);
    return TRUE; }

  else
    return FALSE;
}



/******************************************************************************
*
* ActivatePrevInst()
*
* Tries to find and activate an already open Notepad2 Window
*
*
******************************************************************************/
BOOL CALLBACK EnumWndProc(HWND hwnd,LPARAM lParam)
{

  BOOL bContinue = TRUE;
  char szClassName[64];

  if (GetClassName(hwnd,szClassName,COUNTOF(szClassName)))

    if (lstrcmpi(szClassName,WC_NOTEPAD2) == 0)
    {

      *(HWND*)lParam = hwnd;

      if (IsWindowEnabled(hwnd))
        bContinue = FALSE;

    }

  return(bContinue);

}

BOOL ActivatePrevInst()
{

  HWND hwnd = NULL;
  COPYDATASTRUCT cds;

  if (flagNoReuseWindow || flagStartAsTrayIcon || flagNewFromClipboard || flagPasteBoard)
    return(FALSE);

  EnumWindows(EnumWndProc,(LPARAM)&hwnd);

  // Found a window
  if (hwnd != NULL)
  {
    // Enabled
    if (IsWindowEnabled(hwnd))
    {
      // Make sure the previous window won't pop up a change notification message
      //SendMessage(hwnd,WM_CHANGENOTIFYCLEAR,0,0);

      if (IsIconic(hwnd))
        ShowWindowAsync(hwnd,SW_RESTORE);

      if (!IsWindowVisible(hwnd)) {
        SendMessage(hwnd,WM_TRAYMESSAGE,0,WM_LBUTTONDBLCLK);
        SendMessage(hwnd,WM_TRAYMESSAGE,0,WM_LBUTTONUP); }

      SetForegroundWindow(hwnd);

      if (lpFileArg)
      {
        // Search working directory from second instance, first!
        // lpFileArg is at least MAX_PATH+2 bytes
        char tchTmp[MAX_PATH];

        ExpandEnvironmentStringsEx(lpFileArg,GlobalSize(lpFileArg));

        if (SearchPath(NULL,lpFileArg,NULL,COUNTOF(tchTmp),tchTmp,NULL))
          lstrcpy(lpFileArg,tchTmp);

        else if (PathIsRelative(lpFileArg)) {
          GetCurrentDirectory(COUNTOF(tchTmp),tchTmp);
          PathAppend(tchTmp,lpFileArg);
          lstrcpy(lpFileArg,tchTmp); }

        cds.dwData = DATA_NOTEPAD2_FILEARG;
        cds.cbData = GlobalSize(lpFileArg);
        cds.lpData = lpFileArg;

        // Send lpFileArg to previous instance
        SendMessage(hwnd,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
        GlobalFree(lpFileArg);
      }
      return(TRUE);
    }

    else // IsWindowEnabled()
    {
      // Ask...
      if (IDYES == MsgBox(MBYESNO,IDS_ERR_PREVWINDISABLED))
        return(FALSE);
      else
        return(TRUE);

    }
  }

  else
    return(FALSE);

}


//=============================================================================
//
//  ShowNotifyIcon()
//
//
void ShowNotifyIcon(HWND hwnd,BOOL bAdd)
{

  static HICON hIcon;
  NOTIFYICONDATA nid;

  if (!hIcon)
    hIcon = LoadImage(g_hInstance,MAKEINTRESOURCE(IDR_MAINWND),
                      IMAGE_ICON,16,16,LR_DEFAULTCOLOR);

  ZeroMemory(&nid,sizeof(NOTIFYICONDATA));
  nid.cbSize = sizeof(NOTIFYICONDATA);
  nid.hWnd = hwnd;
  nid.uID = 0;
  nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
  nid.uCallbackMessage = WM_TRAYMESSAGE;
  nid.hIcon = hIcon;
  lstrcpy(nid.szTip,"Notepad2");

  if(bAdd)
    Shell_NotifyIcon(NIM_ADD,&nid);
  else
    Shell_NotifyIcon(NIM_DELETE,&nid);

}


//=============================================================================
//
//  SetNotifyIconTitle()
//
//
void SetNotifyIconTitle(HWND hwnd)
{

  NOTIFYICONDATA nid;
  SHFILEINFO shfi;
  char tchTitle[128];

  ZeroMemory(&nid,sizeof(NOTIFYICONDATA));
  nid.cbSize = sizeof(NOTIFYICONDATA);
  nid.hWnd = hwnd;
  nid.uID = 0;
  nid.uFlags = NIF_TIP;

  if (lstrlen(szCurFile)) {
    SHGetFileInfo2(szCurFile,0,&shfi,sizeof(SHFILEINFO),SHGFI_DISPLAYNAME);
    PathCompactPathEx(tchTitle,shfi.szDisplayName,COUNTOF(tchTitle)-4,0); }
  else
    GetString(IDS_UNTITLED,tchTitle,COUNTOF(tchTitle)-4);

  if (bModified || iCodePage != iInitialCP)
    lstrcpy(nid.szTip,"* ");
  else
    lstrcpy(nid.szTip,"");
  lstrcat(nid.szTip,tchTitle);

  Shell_NotifyIcon(NIM_MODIFY,&nid);

}


//=============================================================================
//
//  InstallFileWatching()
//
//
//void InstallFileWatching(LPCSTR lpszFile)
//{
//
//  char tchDirectory[MAX_PATH];
//  HANDLE hFind;
//
//  // Terminate
//  if (!bEnableFileWatching || !lpszFile || lstrlen(lpszFile) == 0)
//  {
//    if (bRunningWatch)
//    {
//      FindCloseChangeNotification(hChangeHandle);
//      KillTimer(NULL,ID_WATCHTIMER);
//      bRunningWatch = FALSE;
//      bPendingChangeNotify = FALSE;
//    }
//    return;
//  }
//
//  // Install
//  else
//  {
//    // Terminate previous watching
//    if (bRunningWatch) {
//      FindCloseChangeNotification(hChangeHandle);
//      bPendingChangeNotify = FALSE; }
//
//    // No previous watching installed, so launch the timer first
//    else
//      SetTimer(NULL,ID_WATCHTIMER,2000,WatchTimerProc);
//
//      lstrcpy(tchDirectory,lpszFile);
//      PathRemoveFileSpec(tchDirectory);
//
//      // Save data of current file
//      hFind = FindFirstFile(szCurFile,&fdCurFile);
//      if (hFind != INVALID_HANDLE_VALUE)
//        FindClose(hFind);
//      else
//        ZeroMemory(&fdCurFile,sizeof(WIN32_FIND_DATA));
//
//      hChangeHandle = FindFirstChangeNotification(tchDirectory,FALSE,
//        FILE_NOTIFY_CHANGE_FILE_NAME  | \
//        FILE_NOTIFY_CHANGE_DIR_NAME   | \
//        FILE_NOTIFY_CHANGE_ATTRIBUTES | \
//        FILE_NOTIFY_CHANGE_SIZE | \
//        FILE_NOTIFY_CHANGE_LAST_WRITE);
//
//      bRunningWatch = TRUE;
//      bPendingChangeNotify = FALSE;
//    }
//
//  }


//=============================================================================
//
//  WatchTimerProc()
//
//
//void CALLBACK WatchTimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)
//{
//  // Check Change Notification Handle
//  if (WAIT_OBJECT_0 == WaitForSingleObject(hChangeHandle,0))
//  {
//    // Check if the changes affect the current file
//    WIN32_FIND_DATA fdUpdated;
//    HANDLE hFind = FindFirstFile(szCurFile,&fdUpdated);
//    if (hFind)
//      FindClose(hFind);
//    else
//      // The current file has been removed
//      ZeroMemory(&fdUpdated,sizeof(WIN32_FIND_DATA));
//
//    // Check if the file has been changed
//    if (CompareFileTime(&fdCurFile.ftLastWriteTime,&fdUpdated.ftLastWriteTime) != 0 ||
//        fdCurFile.nFileSizeLow != fdUpdated.nFileSizeLow ||
//        fdCurFile.nFileSizeHigh != fdUpdated.nFileSizeHigh)
//    {
//      // Shutdown current watching and give control to main window
//      FindCloseChangeNotification(hChangeHandle);
//      KillTimer(NULL,ID_WATCHTIMER);
//      bRunningWatch = FALSE;
//      bPendingChangeNotify = TRUE;
//      PostMessage(hwndMain,WM_CHANGENOTIFY,0,0);
//    }
//
//    else
//      FindNextChangeNotification(hChangeHandle);
//
//  }
//}



///  End of Notepad2.c  \\\
