title: Custom Find/Replace dialog box
body: <p>First of all, please bear in mind that I'm new to Windows Programming. I'll try to cover my question in great detail, so that hopefully the answer will be too.</p>
  
  <h2>A short introduction:</h2>
  
  <p>I'm <strike>copying</strike> writing a Notepad-like application using Win32 API and pure C. For those of you familiar with Petzold's Windows Programming, this is a modified version of his POPPAD program which he used to describe Common Dialog Boxes. I'm writing this strictly for educational purposes, so please refrain from posting comments like "why you using old technology, use .NET", as those comments will not help me solve my problem :).</p>
  
  <h2>Description of a problem:</h2>
  
  <p>Petzold in his POPPAD program used Common Dialog Boxes to write this Notepad-like application. He used Edit Control to provide all the functions of a basic text editor. POPPAD, much like a Notepad, also had Find and Replace dialog boxes where you could, well, find stuff AND replace it! Mind boggling, I know.</p>
  
  <p>So this is where I wanted to test my newly acquired knowledge from reading the past chapters, as I decided to write my very own Find and Replace dialog box. Granted, it would be in the simplest form possibly. How hard can it be? You have one text field where you enter some text and you have one fancy button which says "Find!" on it.<br />
  Now I'd like to remind you once more that I'm new to Windows programming, so excuse me for any possibly newbie questions. Also, I'd like to point out that I'll focus solely on making the Find dialog box working, as Replace shouldn't be too hard to implement then.</p>
  
  <p>So I played with the resource editor in Visual Studio, and few hours later I got this:<br />
  (stackoverflow doesn't actually allows me to post images, so here's the link below)<br />
  <a href="http://i.imgur.com/R98x4.png" rel="nofollow">http://i.imgur.com/R98x4.png</a></p>
  
  <p>I named this dialog box "Find" (with the quotation marks), so I don't have to use <code>MAKEINTRESOURCE</code> macro in my program, as per Petzold's school of thought. I changed the caption of "Ok" button to "Find Next" and changed it's ID from <code>IDOK</code> to <code>IDC_FIND</code>. Also changed <code>IDCANCEL</code> to <code>IDC_CANCEL</code> and that single line Edit Control is <code>IDC_FIND_FIND</code>.</p>
  
  <p>Now to the more serious things. In my main program's Windows Procedure, I have this piece of code:</p>
  
  <pre><code>case IDM_SEARCH_FIND:
                 hDlgModeless = CreateDialog (hInst, TEXT ("Find"), 
                               hwnd, FindDlgProc) ;
                 return 0 ;
  </code></pre>
  
  <p><code>IDM_SEARCH_FIND</code> is a message identifier of a Menu item, which when clicked should open up the Find dialog box. CreateDialog function is used to create a modeless dialog box and store it's handle into a global variable <code>hDlgModeless</code>. <code>FindDlgProc</code> is name of the dialog box procedure where (I think) all the code of finding the text should go.</p>
  
  <p>So without further ado, here's the code of my Find dialog box procedure:</p>
  
  <pre><code>BOOL CALLBACK FindDlgProc (HWND hDlg, UINT message, 
                          WPARAM wParam, LPARAM lParam)
  {
       static TCHAR     szFindWhat[MAX_STRING_LEN];    //Text to find
       static int       iOffset ;                      //Offset from the beginning of  Edit control to the result
       int              iLength, iPos, iSingleLength ; //Length of a main Edit control and single line Edit control 
       PTSTR            pstrDoc, pstrPos ;
  
       switch (message)
       {
       case WM_INITDIALOG:
            return TRUE ;
  
       case WM_COMMAND:
            switch (LOWORD (wParam))
            {
  
                //If the button "Find Next" has been pressed, process all the logic of finding the text
  
            case IDC_FIND:
  
                        // Get the text from a single-line edit control in Find dialog box
                        // and save it in szFindWhat variable
  
                   iSingleLength = GetWindowTextLength(GetDlgItem(hDlg, IDE_FIND_FIND)) ;
                   GetWindowText(GetDlgItem(hDlg, IDE_FIND_FIND), szFindWhat, iSingleLength)  ;
  
                        // Get the text from a main Edit control, allocate memory for it
                        // and store it in pstrDoc variable
  
                   iLength = GetWindowTextLength (hwndEdit) ;
  
                   if (NULL == (pstrDoc = (PTSTR) malloc ((iLength + 1) * sizeof (TCHAR))))
                        return FALSE ;
  
                   GetWindowText (hwndEdit, pstrDoc, iLength + 1) ;
  
                        // Search the document for the find string
  
                   pstrPos = _tcsstr (pstrDoc + iOffset, szFindWhat) ;
                   free (pstrDoc) ;
  
                        // Return an error code if the string cannot be found
  
                   if (pstrPos == NULL)
                        return FALSE ;
  
                        // Find the position in the document and the new start offset
  
                   iPos = pstrPos - pstrDoc ;
                   iOffset = iPos + lstrlen (szFindWhat) ;
  
                        // Select the found text
  
                   SendMessage (hwndEdit, EM_SETSEL, iPos, iOffset) ;
                   SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0) ;
  
            case IDC_CANCEL:
                 DestroyWindow (hDlg) ;
                 hDlgModeless = NULL ;
                 break ;
            }
            break ;
  
       case WM_CLOSE:
           DestroyWindow (hDlg) ;
           hDlgModeless = NULL ;
           break ;
  
       default:
           return FALSE;
       }
       return FALSE ;
  }
  </code></pre>
  
  <p><br />
  The only actual error I get here is that <code>hwndEdit</code> is undeclared identifier. <code>hwndEdit</code> is the main Edit control (not the single-line in Find dialog box). How do I get the handle to <code>hwndEdit</code> while I'm in a Find dialog box procedure?</p>
  
  <p>I'd like to point out that I'm feeling a bit over my head here, so please say if I'm missing/doing wrong something obvious. I'm pretty sure that even if I fix the only error I'm getting, the program still won't work. Even though the concept of what I should be doing sounds fairly simple, actually programming that seems quite difficult :)</p>
  
  <p>This is what the code above should do, in simplest form:<br />
  - Get the text from Find dialog box which I wish to search<br />
  - Get the text from main Edit control<br />
  - Do a substring search from the last offset (don't start from beginning every time)<br />
  - Find the position of a result and readjust offset<br />
  - Select the found text</p>
  
  <p>I know I haven't really asked a direct question here, well I guess the direct question would be: How do I make this work? :) But more importantly it would be to understand how this exactly works. I'd appreciate if you can provide me with an elaborate answer. Thanks for all the help!</p>