void AnnotateDialog::FindNext(const std::string& searchString,
                              bool caseSensitive,
                              bool searchUp,
                              bool wrapSearch)
{
   unsigned int max = std::numeric_limits<unsigned int>::max();
   bool isFound = false;
   bool isFirstFind = (myFoundLineIndex == max);

   if (searchUp)
   {
      unsigned int begin = (isFirstFind
                            ? myAnnotations->AnnotationCount()-1
                            : myFoundLineIndex-1);
      unsigned int end = 0;

      // As this is unsigned and we're going backwards we must check against
      // max to prevent unsigned int overflow
      for (unsigned int i = begin; i >= end && !isFound && i != max; --i)
         isFound = SetNewLineFoundIfMatches(i, searchString, caseSensitive);

      if (!isFound && !isFirstFind &&
          (wrapSearch || DoYesNoDialog(myFindDialog,
                                       _("Continue search from the end of the file?"), true)))
      {
         begin = myAnnotations->AnnotationCount()-1;
         end = myFoundLineIndex;
         // As this is unsigned and we're going backwards we must check against
         // max to prevent unsigned int overflow
         for (unsigned int i = begin; i >= end && !isFound && i != max; --i)
            isFound = SetNewLineFoundIfMatches(i, searchString, caseSensitive);
      }
   }
   else
   {
      unsigned int begin = (isFirstFind ? 0 : myFoundLineIndex+1);
      unsigned int end = myAnnotations->AnnotationCount();

      for (unsigned int i = begin; i < end && !isFound; ++i)
      {
         isFound = SetNewLineFoundIfMatches(i, searchString, caseSensitive);
      }
      if (!isFound && !isFirstFind &&
          (wrapSearch || DoYesNoDialog(myFindDialog,
                                       _("Continue search from the beginning of the file?"), true)))
      {
         begin = 0;
         end = myFoundLineIndex+1;
         for (unsigned int i = begin; i < end && !isFound; ++i)
            isFound = SetNewLineFoundIfMatches(i, searchString, caseSensitive);
      }
   }
   if (!isFound)
      DoMessageDialog(myFindDialog, _("Search complete"));
}
Beispiel #2
0
bool MyTestApp::OnInit()
{
   YesNoAllDialog::YesNoAll res = DoYesNoAllDialog(0,
                                                   "YesNoAllDialog: Buttons should be centered when the text is too long "
                                                   "to fit on a single line without line breaks", true);
   std::ostringstream ss;
   ss << "Result: " << res;
   DoMessageDialog(0, ss.str());
   
   return true;
}
bool RunExternalMerge(std::string fileMine,
                      std::string fileYours,
                      DirectoryGroups& dirGroups,
                      std::string fileOlder)
{
   TDEBUG_ENTER("RunExternalMerge");
   TDEBUG_TRACE("File mine: " << fileMine);
   TDEBUG_TRACE("File yours: " << fileYours);
   bool bResult = true;
   bool again = false;
   std::string command;
   std::string externalApp;
   std::string externalParams;


   // Perform merge, waiting for it to finish 
   if (fileOlder.empty())
   {
       externalParams = dirGroups.GetStringPreference("External Merge2 Params");
       std::map<std::string, std::string> params;
       params["mine"] = fileMine;
       params["yours"] = fileYours;
       externalParams = ReplaceParams(externalParams, params);
   }
   else
       externalParams = dirGroups.GetStringPreference("External Merge3 Params");

   do
   {
      externalApp = GetExternalApplication("Merge",
                                           dirGroups,
                                           again);

      again = false;
      if (externalApp.empty())
      {
         goto Cleanup;
      }
      command = "\"" + externalApp + "\" " + externalParams;
      if (!LaunchCommand(command, true))
      {
         DoMessageDialog(0, wxString(_("Failed to launch external merge application")) 
                         + wxString(wxT("\n"))
                         + wxString(wxText(command)));
         again = true;
      }
   } while (again);

   bResult = true;

Cleanup:
   return bResult;
}
bool RunExternalDiff(std::string filename1,
                     std::string filename2,
                     DirectoryGroups& dirGroups,
                     std::string filename3)
{
   TDEBUG_ENTER("RunExternalDiff");
   TDEBUG_TRACE("File 1: " << filename1);
   TDEBUG_TRACE("File 2: " << filename2);
   bool bResult = true;
   bool again = false;
   std::string command;
   std::string externalApp;
   std::string externalParams;

   // Perform diff, waiting for it to finish 
   if (filename3.empty())
   {
      externalParams = dirGroups.GetStringPreference("External Diff2 Params");
      std::map<std::string, std::string> params;
      params["1"] = filename1;
      params["2"] = filename2;
      externalParams = ReplaceParams(externalParams, params);
   }
   else
      externalParams = dirGroups.GetStringPreference("External Diff3 Params");

   do
   {
      externalApp = GetExternalApplication("Diff",
                                           dirGroups,
                                           again);
      again = false;
      if (externalApp.empty())
          return false;

      command = "\"" + externalApp + "\" " + externalParams;
      if (!LaunchCommand(command, true))
      {
         DoMessageDialog(0, wxString(_("Failed to launch external diff application"))
                         + wxString(wxT("\n"))
                         + wxString(wxText(command)));
         again = true;
      }
   } while (again);

   return true;
}
bool DoDiff(DirectoryGroups& dirGroups,
            std::string rev1,
            std::string rev2,
            bool forceQuery)
{
   std::string dir = UniqueTemporaryDir();
   AutoDirectoryDeleter dirDeleter(dir);
   std::string diffFile = dir;
   std::string diffFile2 = diffFile;
   bool ok = true;
   CVSAction glue(0);

   if (rev1.empty())
      rev1 = CVSStatus::GetRevisionNumber(dirGroups.mySingleAbsolute);

   // Should we do a text diff only?
   std::string externalApp = GetExternalApplication("Diff",
                                                    dirGroups,
                                                    forceQuery);
   forceQuery = false;
   if (externalApp.empty())
   {
      // Perform a textual diff
      glue.SetProgressFinishedCaption(Printf(_("Finished diff in %s"), 
                                             wxText(dirGroups.mySingleDirectory).c_str()));
      glue.SetProgressCaption(Printf(_("Diffing in %s"), wxText(dirGroups.mySingleDirectory).c_str()));
      MakeArgs args;
      args.add_option("diff");
      args.add_option("-u");
      args.add_option("-r");
      args.add_option(rev1);
      if (!rev2.empty())
      {
         args.add_option("-r");
         args.add_option(rev2);
      }
      args.add_arg(dirGroups.mySingleRelative);

      return glue.Command(dirGroups.mySingleDirectory, args);
   }
   
   bool unixSandbox = IsUnixSandbox(StripLastPart(dirGroups.mySingleAbsolute));

   diffFile += "\\" + MakeRevFilename(ExtractLastPart(dirGroups.mySingleAbsolute), rev1);
   DeleteFileA(diffFile.c_str());
   AutoFileDeleter diffFileDeleter(diffFile);

   AutoFileDeleter diffFile2Deleter;
   if (!rev2.empty())
   {
      diffFile2 += "\\" + MakeRevFilename(ExtractLastPart(dirGroups.mySingleAbsolute), rev2);
      DeleteFileA(diffFile2.c_str());
      diffFile2Deleter.Attach(diffFile2);
   }

   glue.SetProgressFinishedCaption(Printf(_("Finished diff in %s"), 
                                          wxText(dirGroups.mySingleDirectory).c_str()));
   glue.SetProgressCaption(Printf(_("Diffing in %s"), wxText(dirGroups.mySingleDirectory).c_str()));
   std::string cvsroot = CVSStatus::CVSRootForPath(dirGroups.mySingleDirectory);

   CVSServerFeatures sf;
   if (unixSandbox)
       sf.Initialize(&glue);

   // Diffing two revisions
   if (!rev1.empty())
   {
       glue.SetCVSRoot(CVSRoot(cvsroot));
       MakeArgs args;
       std::string tempDir = UniqueTemporaryDir();
       glue.SetCloseIfOK(true);
       args.add_global_option("-f");
       args.add_option("checkout");
       if (rev1 != "HEAD")
       {
           args.add_option("-r");
           args.add_option(rev1);
       }
       args.add_option("-d");
       args.add_option("temp");
       if (unixSandbox)
           sf.AddUnixLineEndingsFlag(args);
       std::string s = EnsureTrailingUnixDelimiter(CVSStatus::CVSRepositoryForPath(dirGroups.mySingleAbsolute))
           + ExtractLastPart(dirGroups.mySingleAbsolute);
       args.add_arg(s);
      
       ok = glue.Command(tempDir, args);
       if (ok)
       {
           // Copy file to destination
           std::string file = EnsureTrailingDelimiter(tempDir) + "temp\\" + ExtractLastPart(dirGroups.mySingleAbsolute);
           SetFileReadOnly(file.c_str(), false);
           CopyFileA(file.c_str(), diffFile.c_str(), false);
           SetFileReadOnly(diffFile.c_str(), true);
       }

       // Erase temporary directory
       DeleteDirectoryRec(tempDir);
     
       if (!ok)
           return false;
       glue.CloseConsoleOutput();
   }
     
   if (!rev2.empty())
   {
       glue.SetCVSRoot(CVSRoot(cvsroot));
       MakeArgs args; 

       std::string tempDir = UniqueTemporaryDir();
       glue.SetCloseIfOK(true);
       args.add_global_option("-f");
       args.add_option("checkout");
       args.add_option("-r");
       args.add_option(rev2);
       args.add_option("-d");
       args.add_option("temp");
       if (unixSandbox)
           sf.AddUnixLineEndingsFlag(args);
       std::string s = EnsureTrailingUnixDelimiter(CVSStatus::CVSRepositoryForPath(dirGroups.mySingleAbsolute))
           + ExtractLastPart(dirGroups.mySingleAbsolute);
       args.add_arg(s);
      
       ok = glue.Command(tempDir, args);

       if (ok)
       {
           // Copy file to destination
           std::string file = EnsureTrailingDelimiter(tempDir) + "temp\\" 
               + ExtractLastPart(dirGroups.mySingleAbsolute);
           SetFileReadOnly(file.c_str(), false);
           CopyFileA(file.c_str(), diffFile2.c_str(), false);
           SetFileReadOnly(diffFile2.c_str(), true);
       }
     
       // Erase temporary directory
       DeleteDirectoryRec(tempDir);

       if (!ok)
           return false;
       glue.CloseConsoleOutput();
   }
    
   if (!FileExists(diffFile.c_str()))
   {
      DoMessageDialog(0, wxString(_("This file is new and has never been committed to the server or is an empty file on the server."))
                      + wxString(wxT("\n\n"))
                      + wxString(wxText(dirGroups.mySingleAbsolute)));
      return true;
   }
    
   do
   {
      externalApp = GetExternalApplication("Diff",
                                           dirGroups,
                                           forceQuery);
      forceQuery = false;
      if (externalApp.empty())
      {
          return false;
      }
      // Perform diff, waiting for it to finish (so we can delete file)
      glue.LockProgressDialog(true);
      if (rev2.empty())
          forceQuery = !RunExternalDiff(diffFile, dirGroups.mySingleAbsolute, dirGroups);
      else
          forceQuery = !RunExternalDiff(diffFile, diffFile2, dirGroups);
      glue.LockProgressDialog(false);
   }
   while (forceQuery);

   return true;
}
// View a revision
bool DoView(DirectoryGroups& dirGroups, std::string rev)
{
   std::string dir = UniqueTemporaryDir();
   std::string viewFile = dir;
   bool ok = true;
   CVSAction glue(0);
   std::string cvsroot;
   bool unixSandbox = IsUnixSandbox(StripLastPart(dirGroups.mySingleAbsolute));

   if (!rev.empty())
   {
      viewFile += "\\" + MakeRevFilename(ExtractLastPart(dirGroups.mySingleAbsolute), rev);
      DeleteFileA(viewFile.c_str());
   }

   glue.SetProgressFinishedCaption(Printf(_("Viewing %s"), 
                                          wxText(dirGroups.mySingleAbsolute).c_str()));
   glue.SetProgressCaption(Printf(_("Viewing %s"), wxText(dirGroups.mySingleAbsolute).c_str()));
   cvsroot = CVSStatus::CVSRootForPath(dirGroups.mySingleDirectory);

   // Viewing revision
   if (!rev.empty())
   {
      glue.SetCVSRoot(CVSRoot(cvsroot));
      MakeArgs args; 
      std::string sTempDir = UniqueTemporaryDir();
      glue.SetCloseIfOK(true);
      args.add_option("checkout");
      if (unixSandbox)
      {
          CVSServerFeatures sf;
          sf.Initialize(&glue);
          sf.AddUnixLineEndingsFlag(args);
      }
      if (rev != "HEAD")
      {
         args.add_option("-r");
         args.add_option(rev);
      }
      args.add_option("-d");
      args.add_option("temp");
      std::string s = EnsureTrailingUnixDelimiter(CVSStatus::CVSRepositoryForPath(dirGroups.mySingleAbsolute))
         + ExtractLastPart(dirGroups.mySingleAbsolute);
      args.add_arg(s);
      
      ok = glue.Command(sTempDir, args);
      if (ok)
      {
         // Copy file to destination
         std::string file = EnsureTrailingDelimiter(sTempDir) + "temp\\" +
            ExtractLastPart(dirGroups.mySingleAbsolute);
         SetFileReadOnly(file.c_str(), false);
         CopyFileA(file.c_str(), viewFile.c_str(), false);
         SetFileReadOnly(viewFile.c_str(), true);
      }

      // Erase temporary directory
      DeleteDirectoryRec(sTempDir);

      if (!ok)
         goto Cleanup;
   }
     
   if (!FileExists(viewFile.c_str()))
   {
      DoMessageDialog(0, wxString(_("This file is new and has never been committed to the server or is an empty file on the server."))
                      + wxString(wxT("\n\n")) 
                      + wxString(wxText(dirGroups.mySingleAbsolute)));
      return true;
   }
   
   // Perform view, waiting for it to finish (so we can delete file)
   glue.LockProgressDialog(true);
   if (rev.empty())
      LaunchFile(dirGroups.mySingleAbsolute, true);
   else
      LaunchFile(viewFile, true);
   glue.LockProgressDialog(false);
    
Cleanup:
   // Clean up
   if (!rev.empty())
   {
      SetFileReadOnly(viewFile.c_str(), false);
      DeleteFileA(viewFile.c_str());
   }
   DeleteDirectoryRec(dir);

   return ok;
}
// Get the annotation list
CAnnotationList* AnnotateDialog::GetAnnotationList(wxWindow* parent)
{
    TDEBUG_ENTER("GetAnnotationList");
    wxBusyCursor();

   // We do not want any progress dialog here
   CVSAction glue(parent);
   glue.SetCloseIfOK(true);
   glue.SetHideStdout();
   wxString title = Printf(_("Annotate %s"), wxText(myFilename).c_str());
   glue.SetProgressCaption(title);

   MakeArgs args;
   args.add_option("annotate");
   // Avoid truncating user names
   args.add_option("-w");
   args.add_option("30");       // Ought to be enough
   // If revision is given, specify it
   if (!myRevision.empty())
   {
      args.add_option("-r");
      args.add_option(myRevision);
   }
   // If we are working on a branch, specify the branch using -r
   else if (CVSStatus::HasStickyTag(myFilename))
   {
      args.add_option("-r");
      args.add_option(CVSStatus::GetStickyTag(myFilename));
   }
   args.add_arg(ExtractLastPart(myFilename));
   bool ok = glue.Command(StripLastPart(myFilename), args);
   if (!ok)
   {
      return 0;
   }
   
   std::string out = glue.GetOutputText();
#if 0
   // Debugging
   std::ifstream in("C:\\cvs-log-output.txt");
   out.clear();
   while (true)
   {
      std::string line;
      std::getline(in, line);
      if (line.empty() && in.eof())
         break;
      out += line;
      out += "\n";
   }
   in.close();
#endif
   FindAndReplace<std::string>(out, "\r\n", "\n");

   if (out.empty())
   {
      wxString s(_("This file is new and has never been committed to the server or is an empty file on the server."));
      s += wxT("\n\n");
      s += wxText(myFilename);
      DoMessageDialog(0, s);
      return 0;
   }

   CAnnotationList* annotationList = new CAnnotationList();

   std::stringstream ifs(out.c_str());

   // Parsing the annotations
   while (true)
   {
      std::string line;
      if (!std::getline(ifs, line) && line.empty())
         break;

      // We need to skip any text which comes before the actual annotations.  A valid
      // annotation starts with the revision number, so we do a simple check to see if
      // the first character is a digit.  This may need to be revised if this assumption
      // is not valid.
      if (!isdigit(line[0]))
         continue;

      annotationList->AddAnnotation(line);
   }
   return annotationList;
}
Beispiel #8
0
/*
 * SpyWindowProc - handle messages for the spy appl.
 */
LRESULT CALLBACK SpyWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    int         check;
    HWND        selwin;
    HWND        hinthwnd;
    WORD        cmdid = 0;
    RECT        area;
    BOOL        pausestate;
    BOOL        spyallstate;
    about_info  ai;
    HMENU       mh;

    switch ( msg ) {
    case WM_CREATE:
        GetClientRect( hwnd, &area );
        mh = GetMenu( hwnd );
        area.top = area.bottom - statusHite;
        StatusHdl = HintWndCreate( hwnd, &area, Instance, NULL );
        statusHite = SizeHintBar( StatusHdl );
        SetHintText( StatusHdl, (MenuItemHint *)menuHints,
                     sizeof( menuHints ) / sizeof( MenuItemHint ) );
        if( SpyMainWndInfo.show_hints ) {
            CheckMenuItem( mh, SPY_SHOW_HELP, MF_CHECKED | MF_BYCOMMAND );
        } else {
            hinthwnd = GetHintHwnd( StatusHdl );
            ShowWindow( hinthwnd, SW_HIDE );
        }
        CreateSpyBox( hwnd );
        SET_WNDINFO( hwnd, (LONG_PTR)SpyListBox );
        CreateSpyTool( hwnd );
        ShowSpyTool( SpyMainWndInfo.show_toolbar );
        if( SpyMainWndInfo.show_toolbar ) {
            CheckMenuItem( mh, SPY_SHOW_TOOLBAR, MF_CHECKED | MF_BYCOMMAND );
        }
        LogInit( hwnd, Instance, SpyLogTitle );
        CheckMenuItem( SpyMenu, SPY_AUTO_SCROLL, MF_CHECKED );
        EnableMenuItem( SpyMenu, SPY_ADD_WINDOW, MF_GRAYED );
        EnableMenuItem( SpyMenu, SPY_STOP, MF_GRAYED );
        EnableMenuItem( SpyMenu, SPY_OFFON, MF_GRAYED );
        if( SpyMainWndInfo.on_top ) {
            CheckMenuItem( mh, SPY_TOP, MF_CHECKED | MF_BYCOMMAND );
            SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
                          SWP_NOMOVE | SWP_NOSIZE );
        }
        break;
    case WM_TIMER:
        // See comment on setUpForPick
        KillTimer( hwnd, wparam );
        switch( wparam ) {
        case SPY_ADD_WINDOW:
            selwin = DoPickDialog( wparam );
            if( selwin != NULL ) {
                setMultipleWindows( hwnd );
                AddSelectedWindow( selwin );
            }
            break;
        case SPY_PEEK_WINDOW:
            DoPickDialog( wparam );
            break;
        case SPY_WINDOW:
            selwin = DoPickDialog( cmdid );
            if( selwin != NULL ) {
                ClearSelectedWindows();
                setSingleWindow( hwnd, selwin );
                enableSpy();
                AddSelectedWindow( selwin );
            }
            break;
        }
        break;
#ifdef __NT__
    case WM_COPYDATA:
        HandleMessage( (LPMSG)((COPYDATASTRUCT *)lparam)->lpData );
        break;
#endif
    case WM_MENUSELECT:
        hinthwnd = GetHintHwnd( StatusHdl );
        HintMenuSelect( StatusHdl, hwnd, wparam, lparam );
        break;
    case WM_COMMAND:
        cmdid = LOWORD( wparam );
        switch( cmdid ) {
        case SPY_SHOW_HELP:
            SpyMainWndInfo.show_hints = !SpyMainWndInfo.show_hints;
            mh = GetMenu( hwnd );
            hinthwnd = GetHintHwnd( StatusHdl );
            if( SpyMainWndInfo.show_hints ) {
                CheckMenuItem( mh, SPY_SHOW_HELP, MF_CHECKED | MF_BYCOMMAND );
                showHintBar( hwnd );
            } else {
                CheckMenuItem( mh, SPY_SHOW_HELP, MF_UNCHECKED | MF_BYCOMMAND );
                ShowWindow( hinthwnd, SW_HIDE );
            }
            GetClientRect( hwnd, &area );
            ResizeSpyBox( area.right - area.left, area.bottom - area.top );
            break;
        case SPY_SHOW_TOOLBAR:
            SpyMainWndInfo.show_toolbar = !SpyMainWndInfo.show_toolbar;
            mh = GetMenu( hwnd );
            if( SpyMainWndInfo.show_toolbar ) {
                CheckMenuItem( mh, SPY_SHOW_TOOLBAR, MF_CHECKED | MF_BYCOMMAND );
            } else {
                CheckMenuItem( mh, SPY_SHOW_TOOLBAR, MF_UNCHECKED | MF_BYCOMMAND );
            }
            ShowSpyTool( SpyMainWndInfo.show_toolbar );
            GetClientRect( hwnd, &area );
            ResizeSpyBox( area.right - area.left, area.bottom - area.top );
            break;
        case SPY_TOP:
            SpyMainWndInfo.on_top = !SpyMainWndInfo.on_top;
            mh = GetMenu( hwnd );
            if( SpyMainWndInfo.on_top ) {
                CheckMenuItem( mh, SPY_TOP, MF_CHECKED | MF_BYCOMMAND );
                SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
                              SWP_NOMOVE | SWP_NOSIZE );
            } else {
                CheckMenuItem( mh, SPY_TOP, MF_UNCHECKED | MF_BYCOMMAND );
                SetWindowPos( hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
                              SWP_NOMOVE | SWP_NOSIZE );
            }
            break;
        case SPY_MARK:
            pausestate = SpyMessagesPaused;
            SpyMessagesPaused = FALSE;              /* make sure marks are
                                                     * always added */
            ProcessMark( hwnd, Instance, markCallback );
            SpyMessagesPaused = pausestate;
            break;
        case SPY_SET_FONT:
            if( ChooseMonoFont( hwnd ) )  {
                statusHite = SizeHintBar( StatusHdl );
                ResetSpyListBox();
                showHintBar( hwnd );
            }
            break;
        case SPY_SAVE_AS:
            SaveListBox( SLB_SAVE_AS, SaveExtra, "", SpyName, hwnd, SpyListBox );
            break;
        case SPY_SAVE:
            SaveListBox( SLB_SAVE_TMP, SaveExtra, ".\\wspy.txt", SpyName, hwnd,
                         SpyListBox );
            break;
        case SPY_LOG:
            if( LogToggle() ) {
                CheckMenuItem( SpyMenu, SPY_LOG, MF_BYCOMMAND | MF_CHECKED );
            } else {
                CheckMenuItem( SpyMenu, SPY_LOG, MF_BYCOMMAND | MF_UNCHECKED );
                CheckMenuItem( SpyMenu, SPY_PAUSE_LOG, MF_BYCOMMAND | MF_UNCHECKED );
            }
            break;
        case SPY_CONFIG_LOG:
            LogConfigure();
            break;
        case SPY_EXIT:
            ClearFilter();
            DestroyWindow( hwnd );
            break;
        case SPY_LIST_BOX:
            switch( GET_WM_COMMAND_CMD( wparam, lparam ) ) {
            case LBN_ERRSPACE:
                ClearSpyBox();
                break;
            case LBN_DBLCLK:
                DoMessageSelDialog( hwnd );
                break;
            }
            break;
        case SPY_SHOW_SELECTED_WINDOWS:
            spyallstate = spyAll;
            DoShowSelectedDialog( hwnd, &spyallstate );
            if( spyallstate ) {
                doSpyAll( hwnd, spyallstate );
                if( spyAll ) {
                    SetSpyState( ON );
                }
                break;
            }
            if( WindowCount == 0 ) {
                SetWindowText( hwnd, SpyName );
                disableSpy();
                break;
            }

            if( WindowCount == 1 ) {
                setSingleWindow( hwnd, WindowList[0] );
            } else {
                setMultipleWindows( hwnd );
            }
            if( SpyState == NEITHER ) {
                enableSpy();
            }
            break;
        case SPY_HELP_CONTENTS:
            if( !WHtmlHelp( hwnd, "spy.chm", HELP_CONTENTS, 0 ) ) {
                WWinHelp( hwnd, "spy.hlp", HELP_CONTENTS, 0 );
            }
            break;
        case SPY_HELP_SRCH:
            if( !WHtmlHelp( hwnd, "spy.chm", HELP_PARTIALKEY, (HELP_DATA)"" ) ) {
                WWinHelp( hwnd, "spy.hlp", HELP_PARTIALKEY, (HELP_DATA)"" );
            }
            break;
        case SPY_HELP_ON_HELP:
            WWinHelp( hwnd, "winhelp.hlp", HELP_HELPONHELP, 0 );
            break;
        case SPY_ABOUT:
            ai.owner = hwnd;
            ai.inst = Instance;
            ai.name = AllocRCString( STR_ABOUT_NAME );
            ai.version = AllocRCString( STR_ABOUT_VERSION );
            ai.first_cr_year = "1993";
            ai.title = AllocRCString( STR_ABOUT_TITLE );
            DoAbout( &ai );
            FreeRCString( ai.name );
            FreeRCString( ai.version );
            FreeRCString( ai.title );
            break;
        case SPY_AUTO_SCROLL:
            if( SpyMessagesAutoScroll ) {
                SpyMessagesAutoScroll = FALSE;
                CheckMenuItem( SpyMenu, SPY_AUTO_SCROLL, MF_UNCHECKED );
            } else {
                SpyMessagesAutoScroll = TRUE;
                CheckMenuItem( SpyMenu, SPY_AUTO_SCROLL, MF_CHECKED );
            }
            break;
        case SPY_PAUSE_LOG:
            if( SpyLogPauseToggle() ) {
                CheckMenuItem( SpyMenu, SPY_PAUSE_LOG,
                               MF_BYCOMMAND | MF_CHECKED );
            } else {
                CheckMenuItem( SpyMenu, SPY_PAUSE_LOG,
                               MF_BYCOMMAND | MF_UNCHECKED );
            }
            break;
        case SPY_PAUSE_MESSAGES:
            SpyMessagePauseToggle();
            break;
        case SPY_CLEAR_MESSAGES:
            ClearSpyBox();
            ClearMessageCount();
            break;
        case SPY_MESSAGES_ASCFG:
            if( AutoSaveConfig ) {
                check = MF_UNCHECKED;
                AutoSaveConfig = FALSE;
            } else {
                AutoSaveConfig = TRUE;
                check = MF_CHECKED;
            }
            CheckMenuItem( SpyMenu, SPY_MESSAGES_ASCFG, check );
            break;
        case SPY_MESSAGES_SAVE:
            DoSaveSpyConfig();
            break;
        case SPY_MESSAGES_LOAD:
            DoLoadSpyConfig();
            break;
        case SPY_MESSAGES_WATCH:
        case SPY_MESSAGES_STOP:
            DoMessageDialog( hwnd, cmdid );
            break;
        case SPY_OFFON:
            if( SpyState != NEITHER ) {
                SetSpyState( !SpyState );
            }
            break;
        case SPY_STOP:
            disableSpy();
            ClearSelectedWindows();
            SetWindowText( hwnd, SpyName );
            break;
        case SPY_ANOTHER_WINDOW:
            if( SpyState == NEITHER || spyAll ) {
                SendMessage( hwnd, WM_COMMAND,
                             GET_WM_COMMAND_MPS( SPY_WINDOW, 0, 0 ) );
            } else {
                SendMessage( hwnd, WM_COMMAND,
                             GET_WM_COMMAND_MPS( SPY_ADD_WINDOW, 0, 0 ) );
            }
            break;
        case SPY_PEEK_WINDOW:
        case SPY_ADD_WINDOW:
        case SPY_WINDOW:
            setUpForPick( hwnd, cmdid );
            break;
        case SPY_ALL_WINDOWS:
            doSpyAll( hwnd, !spyAll );
            if( spyAll ) {
                SetSpyState( ON );
            }
            break;
        }
        break;
#ifdef __NT__
    case WM_NOTIFY:
        if( ((NMHDR *)lparam)->code == NM_DBLCLK &&
            ((NMHDR *)lparam)->idFrom == SPY_LIST_BOX ) {
            DoMessageSelDialog( hwnd );
        }
        break;
#endif
    case WM_CLOSE:
        PostMessage( hwnd, WM_COMMAND, GET_WM_COMMAND_MPS( SPY_EXIT, 0, 0 ) );
        break;
    case WM_ENDSESSION:
        if( wparam ) {
            SpyFini();
        }
        break;
    case WM_DESTROY:
        HintWndDestroy( StatusHdl );
        HintFini();
        StatusWndFini();
        DestroyMonoFonts();
        DestroySpyTool();
        WWinHelp( hwnd, "spy.hlp", HELP_QUIT, 0 );
        PostQuitMessage( 0 );
        break;
    case WM_MOVE:
        GetWindowRect( hwnd, &area );
        if( !SpyMainWndInfo.minimized ) {
            SpyMainWndInfo.last_xpos = SpyMainWndInfo.xpos;
            SpyMainWndInfo.last_ypos = SpyMainWndInfo.ypos;
            SpyMainWndInfo.xpos = area.left;
            SpyMainWndInfo.ypos = area.top;
        }
        break;
    case WM_SIZE:
        if( wparam != SIZE_MAXIMIZED && wparam != SIZE_MINIMIZED ) {
            GetWindowRect( hwnd, &area );
            SpyMainWndInfo.xsize = area.right - area.left;
            SpyMainWndInfo.ysize = area.bottom - area.top;
        } else {
            SpyMainWndInfo.xpos = SpyMainWndInfo.last_xpos;
            SpyMainWndInfo.ypos = SpyMainWndInfo.last_ypos;
        }
        SpyMainWndInfo.minimized = ( wparam == SIZE_MINIMIZED );
        GetClientRect( hwnd, &area );
        area.top = area.bottom - statusHite;
        hinthwnd = GetHintHwnd( StatusHdl );
        MoveWindow( hinthwnd, area.left, area.top,
                    area.right - area.left, statusHite, TRUE );
        ResizeSpyBox( LOWORD( lparam ), HIWORD( lparam ) );
        ResizeSpyTool( LOWORD( lparam ), HIWORD( lparam ) );
        showHintBar( hwnd );
        return( DefWindowProc( hwnd, msg, wparam, lparam ) );
        break;
#if defined( __NT__ )
    case WM_ERASEBKGND: {
        static RECT r;
        GetClientRect( hwnd, &r );
        FillRect( (HDC)wparam, &r, (HBRUSH)(COLOR_BTNFACE + 1) );
        return 1;
    }
#endif
    default:
        return( DefWindowProc( hwnd, msg, wparam, lparam ) );
    }
    return( 0 );

} /* SpyWindowProc */