You don't want to use a hook procedure. The hook procedure can be used to customise the find dialog. The actual find messages are sent to the window identified by hwndOwner. Using a find dialog is a three step process:
1. Register the FINDMSGSTRING at application startup.
2. Call the FindText function with appropriate parameters.
3. Handle the registered find message in the window procedure belonging to hwndOwner.
I have some old code that demonstrates:
Code:
// Global variables.
HWND g_hFndDlg; // Handle for the find dialog
UINT g_uFindReplaceMsg; // Message identifier for FINDMSGSTRING
// Initialization code. Put this at application startup.
// Register message for findDlg
g_uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);
// Call this function to show the find dialog.
BOOL FindDlg(BOOL replace, HWND hwndOwner)
{
// These have to be static (or global) as the
// dialog uses them after the function is finished
static FINDREPLACE frSearch;
static TCHAR findBuffer[256];
static TCHAR replaceBuffer[256];
if (g_hFndDlg)
{
// Find dialog is already open, just activate it...
SetActiveWindow(g_hFndDlg);
// Set find next button focus
SetFocus( GetDlgItem(g_hFndDlg, 1) );
return TRUE;
}
ZeroMemory( &frSearch, sizeof(frSearch) );
frSearch.lStructSize = sizeof(frSearch);
frSearch.hwndOwner = hwndOwner;
frSearch.Flags = FR_HIDEWHOLEWORD | FR_HIDEUPDOWN;
frSearch.lpstrFindWhat = findBuffer;
frSearch.lpstrReplaceWith = replaceBuffer;
frSearch.wFindWhatLen = sizeof(findBuffer) / sizeof(findBuffer[0]);
frSearch.wReplaceWithLen = sizeof(replaceBuffer) / sizeof(replaceBuffer[0]);
// This function is duel use. It will show the replace or find dialogs
// depending on the replace argument...
if (replace)
g_hFndDlg = ReplaceText(&frSearch);
else
g_hFndDlg = FindText(&frSearch);
// Set find next button focus
SetFocus( GetDlgItem(g_hFndDlg,1) );
return TRUE;
}
// This is a mock-up of the hwndOwner window procedure...
static LRESULT CALLBACK DialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
// Handle other messages here...
}
if (msg == g_uFindReplaceMsg)
{
// Message from find dialog box
pFind = (LPFINDREPLACE) lParam;
// If the FR_DIALOGTERM flag is set,
// invalidate the handle identifying the dialog box.
if (pFind->Flags & FR_DIALOGTERM)
{
g_hFndDlg = NULL;
return 0;
}
else if (pFind->Flags & FR_FINDNEXT)
{
// Just find instance of the word
SearchText(pFind); // You provide this function.
}
else if (pFind->Flags & FR_REPLACE)
{
// Delete if you don't need the replace dialog.
// Replace selection if it equals findWhat, then find next instance.
ReplaceWord( pFind, FALSE ); // You provide this function.
}
else if (pFind->Flags & FR_REPLACEALL)
{
// Delete if you don't need the replace dialog.
// Replace all words from end of selection. replaceAllMode set to TRUE.
ReplaceWord( pFind, TRUE ); // You provide this function.
}
return 0;
}
// return DefWindowProc(), etc...
}
The code uses global variables which means you can have only one find dialog open at one time (which is recommended anyway). I'm sure it could be done without globals. The code implements find and replace dialogs as most of the code is shared. Delete the orange code if you only need a find dialog.