-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathMSDNExpertImpl.pas
More file actions
151 lines (131 loc) · 4.02 KB
/
MSDNExpertImpl.pas
File metadata and controls
151 lines (131 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
unit MSDNExpertImpl;
interface
procedure Register;
implementation
uses
ToolsAPI, Windows, Menus, Classes, ShellAPI, SysUtils, WelcomePageIntf;
type
TMSDNHelpExpertBinding = class(TNotifierObject, IOTAKeyboardBinding)
protected
FMSDNQuery: string;
public
constructor Create(const AMSDNQuery: string = '');
procedure MSDNHelp(const Context: IOTAKeyContext;
KeyCode: TShortCut; var BindingResult: TKeyBindingResult);
// IOTAKeyBoardBinding
function GetBindingType: TBindingType;
function GetDisplayName: string;
function GetName: string;
procedure BindKeyboard(const BindingServices: IOTAKeyBindingServices);
end;
procedure Register;
var
KS: IOTAKeyboardServices;
begin
KS := BorlandIDEServices as IOTAKeyBoardServices;
KS.AddKeyboardBinding(TMSDNHelpExpertBinding.Create);
end;
{ TMSDNHelpExpertBinding }
procedure TMSDNHelpExpertBinding.BindKeyboard(
const BindingServices: IOTAKeyBindingServices);
begin
BindingServices.AddKeyBinding([Shortcut(VK_F1, [ssCtrl])], MSDNHelp, nil);
end;
constructor TMSDNHelpExpertBinding.Create(const AMSDNQuery: string = '');
begin
inherited Create;
if AMSDNQuery <> '' then
FMSDNQuery := AMSDNQuery else
FMSDNQuery := 'http://search.microsoft.com/search/results.aspx?view=msdn&qu=%s';
end;
function TMSDNHelpExpertBinding.GetBindingType: TBindingType;
begin
Result := btPartial;
end;
function TMSDNHelpExpertBinding.GetDisplayName: string;
begin
Result := 'Chee Wee''s MSDN Expert';
end;
function TMSDNHelpExpertBinding.GetName: string;
begin
Result := 'chuacw.ProductivityExperts.MSDNHelp';
end;
type
THelpThread = class(TThread)
protected
FSearchString: string;
procedure Execute; override;
public
constructor Create(const ASearchString: string);
end;
constructor THelpThread.Create(const ASearchString: string);
begin
inherited Create(True);
FSearchString := ASearchString;
FreeOnTerminate := True;
Resume;
end;
procedure THelpThread.Execute;
begin
ShellExecute(0, 'open', PChar(FSearchString), nil, nil, SW_SHOW);
end;
procedure TMSDNHelpExpertBinding.MSDNHelp(
const Context: IOTAKeyContext; KeyCode: TShortCut;
var BindingResult: TKeyBindingResult);
var
ep: IOTAEditPosition;
EditView: IOTAEditView;
CursorPos: TOTAEditPos;
StartCol, EndCol, WordLen, Element, LineFlag: Integer;
Identifier, LQueryString: string;
begin
EditView := Context.EditBuffer.TopView;
ep := EditView.Position;
CursorPos := EditView.CursorPos;
EditView.GetAttributeAtPos(CursorPos, True, Element, LineFlag);
if Element = atWhiteSpace then
begin
Dec(CursorPos.Col);
EditView.GetAttributeAtPos(CursorPos, True, Element, LineFlag);
if Element = atWhiteSpace then
begin
Inc(CursorPos.Col, 2);
EditView.GetAttributeAtPos(CursorPos, True, Element, LineFlag);
end;
end;
if Element in [atIdentifier, atReservedWord] then
begin
// The cursor can be anywhere on the word, or at the end of a word
// If cursor is at the middle of a word, then extract the word
if ep.IsWordCharacter then
begin
ep.Save;
try
EndCol := CursorPos.Col;
while (ep.IsWordCharacter) and (ep.Column > 1) do
ep.MoveRelative(0, -1);
StartCol := ep.Column + 1;
WordLen := EndCol - StartCol;
ep.Move(ep.Row, EndCol);
while ep.IsWordCharacter do
begin
ep.MoveRelative(0, 1);
Inc(WordLen);
end;
ep.MoveRelative(0, -WordLen);
Identifier := ep.Read(WordLen);
finally
ep.Restore;
end;
end else
begin
// If cursor is at the end of a word, then extract it
Identifier := ep.RipText('_', rfBackward or rfIncludeAlphaChars or rfIncludeNumericChars);
end;
LQueryString := Format(FMSDNQuery, [Identifier]);
// Run search in background so as not to suspend IDE
if not GoURL(LQueryString) then
THelpThread.Create(LQueryString);
end;
end;
end.