【发布时间】:2011-06-30 18:45:02
【问题描述】:
首先,请记住,我是 Windows 编程新手。我会尽量详细地回答我的问题,希望答案也是如此。
简短介绍:
我正在复制使用 Win32 API 和纯 C 编写一个类似记事本的应用程序。对于那些熟悉 Petzold 的 Windows 编程的人,这是他以前的 POPPAD 程序的修改版本描述通用对话框。我写这篇文章是为了教育目的,所以请不要发布类似“你为什么使用旧技术,使用 .NET”这样的 cmets,因为这些 cmets 不会帮助我解决我的问题 :)。
问题描述:
Petzold 在他的 POPPAD 程序中使用通用对话框来编写这个类似记事本的应用程序。他使用 Edit Control 来提供基本文本编辑器的所有功能。 POPPAD,很像记事本,也有查找和替换对话框,您可以在其中找到并替换它!令人难以置信,我知道。
所以我想在这里测试我通过阅读过去的章节获得的新知识,因为我决定编写自己的查找和替换对话框。当然,它可能是最简单的形式。它能有多难?您有一个文本字段,您可以在其中输入一些文本,并且您有一个花哨的按钮,上面写着“查找!”就可以了。
现在我想再次提醒您,我是 Windows 编程的新手,所以请原谅我有任何可能是新手的问题。另外,我想指出,我将只专注于使 Find 对话框正常工作,因为 Replace 应该不会太难实现。
所以我在 Visual Studio 中使用了资源编辑器,几个小时后我得到了这个:
(stackoverflow 实际上并不允许我发布图片,所以这是下面的链接)
http://i.imgur.com/R98x4.png
我将此对话框命名为“查找”(带引号),因此按照 Petzold 的思想,我不必在我的程序中使用 MAKEINTRESOURCE 宏。我将“确定”按钮的标题更改为“查找下一个”,并将其 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 的句柄?
我想指出,我在这里感觉有点过头了,所以请说我是否遗漏/做错了一些明显的事情。我很确定即使我修复了我遇到的唯一错误,该程序仍然无法运行。尽管我应该做什么的概念听起来很简单,但实际上编程似乎相当困难:)
这是上面的代码应该做的,最简单的形式:
- 从“查找”对话框中获取我希望搜索的文本
- 从主编辑控件获取文本
- 从最后一个偏移量进行子字符串搜索(不要每次都从头开始)
- 查找结果的位置并重新调整偏移量
- 选择找到的文字
我知道我在这里并没有真正提出直接的问题,我想直接的问题是:我该如何进行这项工作? :) 但更重要的是要了解这究竟是如何工作的。如果您能给我一个详尽的答案,我将不胜感激。感谢大家的帮助!
【问题讨论】: