00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "precomp.h"
00022
#pragma hdrstop
00023
00024
00025 #define SEARCH_STRING_LENGTH (80)
00026
00027
USHORT
00028 SearchForString(
00029 IN
PSCREEN_INFORMATION ScreenInfo,
00030 IN PWSTR SearchString,
00031 IN USHORT StringLength,
00032 IN BOOLEAN IgnoreCase,
00033 IN BOOLEAN Reverse,
00034 OUT PCOORD StringPosition
00035 )
00036 {
00037
PCONSOLE_INFORMATION Console;
00038 COORD MaxPosition;
00039 COORD EndPosition;
00040 COORD Position;
00041
BOOL RecomputeRow;
00042
SHORT RowIndex;
00043
PROW Row;
00044
USHORT ColumnWidth;
00045 WCHAR SearchString2[
SEARCH_STRING_LENGTH * 2 + 1];
00046 PWSTR pStr;
00047
00048 Console = ScreenInfo->Console;
00049
00050 MaxPosition.X = ScreenInfo->ScreenBufferSize.X -
StringLength;
00051 MaxPosition.Y = ScreenInfo->ScreenBufferSize.Y - 1;
00052
00053
00054
00055
00056
00057
if (Console->
Flags &
CONSOLE_SELECTING) {
00058 Position.X = Console->
SelectionAnchor.X;
00059 Position.Y = Console->
SelectionAnchor.Y;
00060 }
else if (Reverse) {
00061 Position.X = 0;
00062 Position.Y = 0;
00063 }
else {
00064 Position.X = MaxPosition.X;
00065 Position.Y = MaxPosition.Y;
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
ASSERT(
StringLength == wcslen(SearchString) &&
StringLength <
ARRAY_SIZE(SearchString2));
00075
00076 pStr = SearchString2;
00077
while (*SearchString) {
00078 *pStr++ = *SearchString;
00079
#if defined(CON_TB_MARK)
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
#else
00094
00095
00096
00097
00098
00099
#endif
00100
if (IsConsoleFullWidth(Console->
hDC, Console->
CP, *SearchString)) {
00101
#if defined(CON_TB_MARK)
00102
*pStr++ = CON_TB_MARK;
00103
#else
00104
*pStr++ = *SearchString;
00105
#endif
00106
}
00107 ++SearchString;
00108 }
00109
00110 *pStr =
L'\0';
00111 ColumnWidth = (
USHORT)(pStr - SearchString2);
00112 SearchString = SearchString2;
00113
00114
00115
00116
00117
00118
StringLength = ColumnWidth *
sizeof(WCHAR);
00119
00120
00121
00122
00123
00124 RecomputeRow =
TRUE;
00125 EndPosition = Position;
00126
do {
00127
#if !defined(CON_TB_MARK)
00128
#if DBG
00129
int nLoop = 0;
00130
#endif
00131
recalc:
00132
#endif
00133
if (Reverse) {
00134
if (--Position.X < 0) {
00135 Position.X = MaxPosition.X;
00136
if (--Position.Y < 0) {
00137 Position.Y = MaxPosition.Y;
00138 }
00139 RecomputeRow =
TRUE;
00140 }
00141 }
else {
00142
if (++Position.X > MaxPosition.X) {
00143 Position.X = 0;
00144
if (++Position.Y > MaxPosition.Y) {
00145 Position.Y = 0;
00146 }
00147 RecomputeRow =
TRUE;
00148 }
00149 }
00150
if (RecomputeRow) {
00151 RowIndex = (ScreenInfo->BufferInfo.TextInfo.FirstRow + Position.Y) % ScreenInfo->ScreenBufferSize.Y;
00152 Row = &ScreenInfo->BufferInfo.TextInfo.Rows[RowIndex];
00153 RecomputeRow =
FALSE;
00154 }
00155
#if !defined(CON_TB_MARK)
00156
ASSERT(nLoop++ < 2);
00157
if (Row->
CharRow.KAttrs && (Row->
CharRow.KAttrs[Position.X] & ATTR_TRAILING_BYTE)) {
00158
goto recalc;
00159 }
00160
#endif
00161
if (!
MyStringCompareW(SearchString, &Row->
CharRow.
Chars[Position.X],
StringLength, IgnoreCase)) {
00162 *StringPosition = Position;
00163
return ColumnWidth;
00164 }
00165 }
while (!(Position.X == EndPosition.X && Position.Y == EndPosition.Y));
00166
00167
return 0;
00168 }
00169
00170 INT_PTR
00171 FindDialogProc(
00172 HWND hWnd,
00173 UINT Message,
00174 WPARAM wParam,
00175 LPARAM lParam
00176 )
00177 {
00178
PCONSOLE_INFORMATION Console;
00179
PSCREEN_INFORMATION ScreenInfo;
00180
USHORT StringLength;
00181
USHORT ColumnWidth;
00182 WCHAR szBuf[
SEARCH_STRING_LENGTH + 1];
00183 COORD Position;
00184 BOOLEAN IgnoreCase;
00185 BOOLEAN Reverse;
00186
00187
switch (Message) {
00188
case WM_INITDIALOG:
00189
SetWindowLongPtr(
hWnd, DWLP_USER, lParam);
00190
SendDlgItemMessage(
hWnd,
ID_FINDSTR, EM_LIMITTEXT,
ARRAY_SIZE(szBuf)-1, 0);
00191
CheckRadioButton(
hWnd,
ID_FINDUP,
ID_FINDDOWN,
ID_FINDDOWN);
00192
return TRUE;
00193
case WM_COMMAND:
00194
switch (LOWORD(wParam)) {
00195
case IDOK:
00196
StringLength = (
USHORT)
GetDlgItemText(
hWnd,
ID_FINDSTR, szBuf,
ARRAY_SIZE(szBuf));
00197
if (
StringLength == 0) {
00198
break;
00199 }
00200 IgnoreCase =
IsDlgButtonChecked(
hWnd,
ID_FINDCASE) == 0;
00201 Reverse =
IsDlgButtonChecked(
hWnd,
ID_FINDDOWN) == 0;
00202 Console = (
PCONSOLE_INFORMATION)
GetWindowLongPtr(
hWnd, DWLP_USER);
00203 ScreenInfo = Console->
CurrentScreenBuffer;
00204
if ((ColumnWidth =
SearchForString(ScreenInfo, szBuf,
StringLength, IgnoreCase, Reverse, &Position)) != 0) {
00205
00206
00207
00208
00209
00210
if (Console->
Flags &
CONSOLE_SELECTING) {
00211
ClearSelection(Console);
00212 }
00213
00214
00215
00216
00217
00218 Console->
Flags |=
CONSOLE_SELECTING;
00219 Console->
SelectionFlags =
CONSOLE_MOUSE_SELECTION |
CONSOLE_SELECTION_NOT_EMPTY;
00220 Console->
SelectionAnchor = Position;
00221 Console->
SelectionRect.Left = Console->
SelectionAnchor.X;
00222 Console->
SelectionRect.Right = Console->
SelectionRect.Left + ColumnWidth - 1;
00223 Console->
SelectionRect.Top = Console->
SelectionRect.Bottom = Console->
SelectionAnchor.Y;
00224
MyInvert(Console,&Console->
SelectionRect);
00225
SetWinText(Console,
msgSelectMode,
TRUE);
00226
00227
00228
00229
00230
00231
if (Console->
SelectionRect.Left < ScreenInfo->
Window.Left) {
00232 Position.X = Console->
SelectionRect.Left;
00233 }
else if (Console->
SelectionRect.Right > ScreenInfo->
Window.Right) {
00234 Position.X = Console->
SelectionRect.Right -
CONSOLE_WINDOW_SIZE_X(ScreenInfo) + 1;
00235 }
else {
00236 Position.X = ScreenInfo->
Window.Left;
00237 }
00238
if (Console->
SelectionRect.Top < ScreenInfo->
Window.Top) {
00239 Position.Y = Console->
SelectionRect.Top;
00240 }
else if (Console->
SelectionRect.Bottom > ScreenInfo->
Window.Bottom) {
00241 Position.Y = Console->
SelectionRect.Bottom -
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) + 1;
00242 }
else {
00243 Position.Y = ScreenInfo->
Window.Top;
00244 }
00245
SetWindowOrigin(ScreenInfo,
TRUE, Position);
00246
return TRUE;
00247 }
else {
00248
00249
00250
00251
00252
00253 Beep(800, 200);
00254 }
00255
break;
00256
case IDCANCEL:
00257
EndDialog(
hWnd, 0);
00258
return TRUE;
00259 }
00260
break;
00261
default:
00262
break;
00263 }
00264
return FALSE;
00265 }
00266
00267
VOID
00268 DoFind(
00269 IN
PCONSOLE_INFORMATION Console
00270 )
00271 {
00272 DialogBoxParam(
ghInstance,
00273 MAKEINTRESOURCE(
ID_FINDDLG),
00274 Console->hWnd,
00275
FindDialogProc,
00276 (LPARAM)Console);
00277 }