c - 自定义查找/替换对话框

标签 c windows winapi

首先,请记住我是Windows编程新手。我会尽量详细地回答我的问题,希望答案也能如此。
简短介绍:
我正在使用Win32 API和纯C编写一个类似记事本的应用程序。对于熟悉Petzold的Windows编程的人来说,这是他的POPPAD程序的一个修改版本,他用来描述常见的对话框。我写这篇文章是为了教育目的,所以请不要发表诸如“为什么使用旧技术,使用.NET”之类的评论,因为这些评论无助于我解决问题:)。
问题描述:
Petzold在他的POPPAD程序中使用通用对话框编写这个类似记事本的应用程序。他使用编辑控件来提供基本文本编辑器的所有功能。POPPAD很像记事本,也有查找和替换对话框,在那里你可以,嗯,找到东西并替换它!令人难以置信,我知道。
所以这是我想测试我从阅读过去章节中获得的新知识的地方,因为我决定编写我自己的“查找和替换”对话框。当然,它可能是最简单的形式。有多难?你有一个文本字段,在其中输入一些文本,你有一个花哨的按钮,上面写着“查找!”在上面。
现在我想再次提醒你,我对Windows编程还不熟悉,所以请原谅我有任何可能是新手的问题。另外,我想指出的是,我将只专注于使Find对话框工作,因为Replace不应该太难实现。
所以我在Visual Studio中使用了资源编辑器,几个小时后我得到了这个:
(stackoverflow实际上不允许我发布图片,所以下面是链接)
http://i.imgur.com/R98x4.png
我将这个对话框命名为“Find”(带引号),这样我就不必在程序中使用MAKEINTRESOURCE宏了,这符合Petzold的思想。我把“Ok”按钮的标题改成了“Find Next”,并把它的ID从IDOK改成IDC_FIND。也将IDCANCEL更改为IDC_CANCEL,并且单行编辑控件为IDC_FIND_FIND
现在来看看更严重的事情。在主程序的Windows过程中,我有一段代码:

case IDM_SEARCH_FIND:
               hDlgModeless = CreateDialog (hInst, TEXT ("Find"), 
                             hwnd, FindDlgProc) ;
               return 0 ;

IDM_SEARCH_FIND是菜单项的消息标识符,单击它将打开“查找”对话框。CreateDialog函数用于创建非模式对话框,并将其句柄存储到全局变量hDlgModeless中。FindDlgProc是对话框过程的名称,在这里(我认为)查找文本的所有代码都应该放在这里。
因此,无需再费吹灰之力,以下是“我的查找”对话框过程的代码:
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 ;
}

我在这里得到的唯一实际错误是hwndEdit是未声明的标识符。hwndEdit是主编辑控件(不是“查找”对话框中的单行)。在查找对话框过程中,如何获取hwndEdit的句柄?
我想指出的是,我在这里感觉有点过头了,所以请说,如果我错过了/做错了一些显而易见的事情。我很确定,即使我修复了唯一的错误,程序仍然无法工作。尽管我应该做什么的概念听起来相当简单,但实际上编程似乎相当困难:)
以上代码应以最简单的形式执行以下操作:
-从“查找”对话框中获取要搜索的文本
-从主编辑控件获取文本
-从最后一个偏移量执行子字符串搜索(不要每次都从头开始)
-找到结果的位置并重新调整偏移量
-选择找到的文本
我知道我并没有直接问这个问题,我想直接的问题是:我该怎么做?)但更重要的是要了解这到底是如何运作的。如果你能给我一个详细的答复,我将不胜感激。谢谢你的帮助!

最佳答案

看起来你离得很近,你只需要从主窗口获取hwndEdit。您将主窗口的句柄作为父窗口传递给了对话框,因此您应该能够获得对话框的父窗口,如下所示:

HWND hwndParent = GetParent(hDlg);

之后,您可以通过引用主窗口定义中的编辑控件ID从该父控件获取编辑控件。类似的内容(假设控件ID是IDC_EDIT):
HWND hwndEdit = GetDlgItem(hwndParent, IDC_EDIT);

关于c - 自定义查找/替换对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6539582/

相关文章:

c++ - 使用 WriteConsoleOutputCharacter 和 SetConsoleTextAttribute

c++ - 在 RichEdit winapi 中隐藏插入符号

Python netifaces 模块 Windows 安装

windows - 复制文件安全权限

C win32包装器

c# - 如何计算每对字母的字距调整?

c - 不明白为什么我的乘法不起作用?

c - Windows 上的 GCC : Set "Description" field of C executable?

c - 包装来自静态库错误的函数调用

windows - 缓存系统应该在 Windows 上使用多少内存?