Found := False;
while IsWindow(wnd) do begin
GetClassName(wnd, ClassName, 80);
if lstrcmpi(ClassName, ''''SysTreeView32'''')=0 then begin
Found := True;
Break;
end;
wnd := GetWindow(wnd, GW_HWNDNEXT);
end;
if not Found then Exit;
为了能够让插入的ComboBox和其他窗口控件的布局协调一致,首先需要找到用来显示文件夹的TreeView窗口。我的计划是:让ComboBox占据TreeView原来的位置(当然它的高度要比TreeView小得多),然后,包括TreeView在内的其他窗口依次下移。下面是实现代码:
// Add combo Box and move other controls down
GetWindowRect(wnd, rc);
ScreenToClient(AWnd, rc.TopLeft);
ScreenToClient(AWnd, rc.BottomRight);
wndCombo := CreateWindow(''''COMBOBOX'''', '''''''',
WS_CHILD or WS_VISIBLE or CBS_DROPDOWNLIST or CBS_OWNERDRAWFIXED or CBS_HASSTRINGS,
rc.Left, rc.Top,
rc.Right-rc.Left, rc.Bottom-rc.Top,
AWnd, HMENU(IDC_COMBO),
HInstance, nil);
SendMessage(wndCombo, WM_SETFONT,
SendMessage(AWnd, WM_GETFONT, 0, 0),
1);
OldStyle := GetWindowLong(wnd, GWL_STYLE);
SetWindowLong(wnd, GWL_STYLE, OldStyle or TVS_SHOWSELALWAYS);
SaveRect := rc;
wnd := GetWindow(AWnd, GW_CHILD);
while IsWindow(wnd) do begin
GetWindowRect(wnd, rc);
ScreenToClient(AWnd, rc.TopLeft);
ScreenToClient(AWnd, rc.BottomRight);
if (wnd<>wndCombo) and (rc.Top>=SaveRect.Top) then
SetWindowPos(wnd, HWND_NOTOPMOST, rc.Left, rc.Top+40, 0, 0, SWP_NOSIZE or SWP_NOZORDER);
wnd := GetWindow(wnd, GW_HWNDNEXT);
end;
GetWindowRect(AWnd, rc);
SetWindowPos(AWnd, HWND_NOTOPMOST, 0, 0, rc.Right-rc.Left, rc.Bottom-rc.Top+40, SWP_NOMOVE or SWP_NOZORDER);
如果你过去很少用API写程序,那么这些代码可能让你看得有点头晕。基本上上述程序完成如下的工作:
(1)计算TreeView在窗口中的位置;
(2)建立ComboBox窗口,并基于TreeView的位置将它放置到合理的地方;
(3)将ComboBox的字体设置为和整个窗体的字体相同(这一步是必要的,否则显示的效果会很难看);
(4)为TreeView的窗口风格添加TVS_SHOWSELALWAYS位,从而在焦点移动到ComboBox的时候,仍然可以明显的观察到TreeView中究竟选中了哪个项目;
(5)将窗口中的其他控件依次下移,从而为ComboBox腾出必要的空间;
(6)将窗口本身的高度也略微放大,从而适应添加ComboBox以后的大小。
下一步就是向ComboBox中增加一些表项,否则的话它就是一个鸡肋。我决定添加两种项目:(1)系统中的某些特殊路径,这些路径可以通过SHGetSpecialFolderLocation获得;(2)通常的文件路径。为了让代码简洁一些,我增加了一个辅助函数:
procedure InsertComboItem(hCombo:HWND; const Text:string; data:DWORD);
var
nIndex : integer;
begin
nIndex := SendMessage(hCombo, CB_ADDSTRING, 0, LongInt(PChar(Text)));
SendMessage(hCombo, CB_SETITEMDATA, nIndex, data);
end;
然后在AdjustDlg函数的末尾添加如下的代码:
InsertComboItem(wndCombo, '''''''', CSIDL_DESKTOP);
InsertComboItem(wndCombo, '''''''', CSIDL_FAVORITES);
InsertComboItem(wndCombo, '''''''', CSIDL_STARTMENU);
InsertComboItem(wndCombo, '''''''', CSIDL_DRIVES);
InsertComboItem(wndCombo, ''''c:\'''', 555);
InsertComboItem(wndCombo, ''''d:\winnt'''', 555);
InsertComboItem(wndCombo, ''''c:\windows\system'''', 555);
这里用555并没有什么特别的意义。我本来想用0来标志普通文件夹,但后来发现CSIDL_DESKTOP正是定义为0,所以必须用其他数字来区分。555是我信手写的,你当然可以用别的数字,只要注意不要和预定义的CSIDL常量冲突即可。
AdjustDlg函数的内容就这么多。接下来是NewBrowseProc函数的内容,它的基本结构如下:
function NewBrowseProc(AWnd:HWND; uMsg:UINT; wp:WPARAM; lp:LPARAM):LongInt; stdcall;
begin
Result := 0;
case uMsg of
…
end;
if Assigned(OldBrowseProc) then
Result := OldBrowseProc(AWnd, uMsg, wp, lp); 上一页 [1] [2] [3] [4] 下一页 [常用软件]Window Media Player 播放器 [Delphi程序]Window SubClassing之另类运用(之一) [Delphi程序]override deal with window closing in database … [Delphi程序]Window 消息大全使用详解 [网页制作]Chromeless Window For IE6 SP1 [网页制作]关于Web设计、开发中window对象的资料 [Web开发]JavaScript : WINDOW FOR JAVASCRIPT [Web开发]JavaScript关于window.open()应用 [Web开发]关于Web设计、开发中window对象的资料 [Web开发]Javascript:window对象的方法
|