There is a simple workaround. It could be even simpler, but Delphi 2 (in opposite to more recent Delphi versions) caused massive flickering during resizing. So here is a fully compatible solution (note: typecasting to HINST(@...) is to maintain compatibility with both 32-bit and 64-bit code). Tested with Win2k and WinXP - as 32-bit code, but should also work as 64-bit without any problems.
Add declarations to the TMyComboBox class definition:
Code: Select all
TMyComboBox = class(TComboBox)
...
...
protected
procedure CreateWnd; override;
procedure WMDestroy(var Message : TWMDestroy); message WM_DESTROY;
procedure WMSize(var Message : TWMSize); message WM_SIZE;
private
OrigEditProc : Pointer;
ResizeCounter : Integer;
CurrentSelectionStart : Integer;
CurrentSelectionEnd : Integer;
...
...
end;
Code: Select all
{Subclassed window procedure for internal edit control - overrides new selection}
function SubclassedEditProc(Window : HWND; MessageCode : UINT; wParam : WPARAM; lParam : LPARAM) : LRESULT; stdcall;
begin
with TMyComboBox(FindControl(GetParent(Window))) do
begin
if MessageCode = EM_SETSEL then
if ResizeCounter <> 0 then
begin
wParam:=CurrentSelectionStart;
lParam:=CurrentSelectionEnd;
end;
if not IsWindowUnicode(Window) then
Result:=CallWindowProcA(OrigEditProc,Window,MessageCode,wParam,lParam)
else
Result:=CallWindowProcW(OrigEditProc,Window,MessageCode,wParam,lParam);
end;
end;
{Subclassing internal edit control}
procedure TMyComboBox.CreateWnd;
begin
inherited;
if Win32Platform = VER_PLATFORM_WIN32_NT then
if EditHandle <> 0 then
begin
OrigEditProc:=Pointer(GetWindowLong(EditHandle,GWL_WNDPROC));
SetWindowLong(EditHandle,GWL_WNDPROC,HINST(@SubclassedEditProc));
end;
end;
{Unsubclassing internal edit control}
procedure TMyComboBox.WMDestroy(var Message : TWMDestroy);
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
if EditHandle <> 0 then
SetWindowLong(EditHandle,GWL_WNDPROC,HINST(OrigEditProc));
inherited;
end;
{Combobox resize handler - remembers current selection}
procedure TMyComboBox.WMSize(var Message : TWMSize);
begin
Inc(ResizeCounter);
try
Perform(CB_GETEDITSEL,HINST(@CurrentSelectionStart),HINST(@CurrentSelectionEnd));
inherited;
finally
Dec(ResizeCounter);
end;
end;