如何在一个独立的线程中弹出POPUP菜单(100分)

  • 主题发起人 主题发起人 peng_qs
  • 开始时间 开始时间
P

peng_qs

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大侠,
我现在在做一个利用串口传送数据的托盘程序,经调试发现,在用户点击
托盘菜单时会导致主进程被挂起,无法正确处理接收到的数据,故此想在一个
独立的线程中实现POPUP MENU的弹出操作,但总是无法将菜单弹出,不知
哪位大侠可以提供高见.谢谢

procedure TPCDataLink.IconTray (var Msg: TMessage);
var
hHandle: THandle;
ThreadId1: DWORD;
retCode: DWORD;
p : Pointer;
begin
if (Msg.lParam = wm_rbuttondown) then
begin
if not bHasPopuped then
begin
retCode := 0;
bHasPopuped := True;
p := @PopupMenu1;
hHandle := CreateThread( nil, 0, @PCDataLink_ThreadFunc, p, 0, ThreadId1 );
if hHandle <> 0 then
begin
While Truedo
begin
if not GetExitCodeThread(hHandle,retCode) then
break;
If retCode <> STILL_ACTIVE then
Break;
Application.ProcessMessages;
end;
end;
bHasPopuped := False;
end;
end;
end;

function PCDataLink_ThreadFunc( pInfo : Pointer): Integer;
stdcall;
var
Pt: TPoint;
retCode : Integer;
begin
Try
GetCursorPos (Pt);
TPopupMenu(pInfo^).Popup (Pt.x, Pt.y);
retCode := 0;
except
retCode := 1;
end;
ExitThread( retCode );
Result := retCode;
end;
 
调个个儿,将串口数据传送放到线程中,如何?
 
提问者:
如果你还要继续讨论请定期提前你的帖子,如果不想继续讨论请结束帖子。
请认真阅读大富翁论坛规则说明 http://www.delphibbs.com/delphibbs/rules.asp
 
转贴,能够解释这个问题:
Hi All,
in the previous letter I thanked VCL designers for their
good work, but now I want to ask why theydo
ne so strange
implementation to bring up pop-up menu?
I need to open several different forms in different threads
but within single application. Forms should work independently
each other. I create a thread where I dynamically create
an exemplar of TApplication:
procedure TMyThread.Execute ();
var
Application: TApplication;
begin
FreeOnTerminate := true;
Application := TApplication.Create (nil);
Form1 := TForm1.Create (Application);
// messages-processing loop for Delphi forms
repeat
Application.HandleMessage();
until Application.Terminated;
Application.Free();
end;

All work very well except pop-up menusdo
esn't bring
in the second and next forms. I made study what causes
problem, and I found that in unit menus.pas class TPopupList
is declared. It is intended to store pop-up menus for whole
applications and also has special invisible window
(its handler) for showing pop-up menu. This ONE window
is used to show ANY pop-up menu for ANY forms of application.
The special window is created only once when the first pop-up
menu is being created:
procedure TPopupList.Add(Popup: TPopupMenu);
begin
if Count = 0 then
Window := AllocateHWnd(WndProc);
inherited Add(Popup);
end;

The fact is that an exemplar of TPopupList is a global
variable which declared in menus.pas as well for whole
application! How is a pop-up menu bringed up? With the help
of TrackPopupMenu function. This function displays a floating
pop-up menu at the specified location and tracks the selection
of items on the pop-up menu.
But this function is thread depended! If handle of menu and
handle of window belong to pop-up menu and window for which the
pop-up menu is displayed that were created in different threads,
the function fails. Both windows, pop-up menu window and its
onwer window must be created in the same thread otherwise
TrackPopupMenu may not be used.
The problem may be resolved by creating individual special
window for each pop-up menu. It is easy to implement, it needs
to slightly modify TPopupList class declared in menus.pas.
I hope VCL designers will pay attention such problem in the
next releases either VCL or ever CLX. :-)
 
接受答案了.
 
后退
顶部