参考 ALWAYSONTOP 属性 和顶层窗体属性(showwindow)
那问题就复杂多了 要用API了
给你点参考
第一个问题很简单,用一个API 就可搞定,
预备知识:Application 为WINDOWS的主窗口,但程序中可见主窗口(如Form1),是子窗体,在任务栏中的那标是 Application 的,并不是Form1的
setwindowlong(application.handle,gwl_exstyle,ws_ex_toolwindow);
句柄 风格 工具工窗 (只是这英文译意)
{让窗口在运行时不在任务栏 上出现按钮}
第一个参数是 窗口的句柄
后两个是具体参数,我也是菜鸟,如果你想知详细可查MSDN ,呵呵
------------------------------------------------------------------------
预备知识:对象指针传递在前加@
在DELPHI下,处理一特定消息,要写专门的过程,
procedure TrayOnMouse(var Msg: TMessage); message WM_User + 10;
^^^^^^ ^^^^^^^^^
专一个Tmessage的指针 ,这里是在前加 var 后加message关键字,接要补获的消息
第二个问题就复杂,我才做过, 所以比较清楚
用Shell_NotifyIconA() API 添加一图标到托盘 ,用它之前要先Uses ShellApi;
在C的声明是: Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);
第一个参数是 操作方式:
NIM_ADD:增加一个图标 ;
NIM_MODIFY:修改一个已有的图标 ;
NIM_DELETE:删除一个;
第二个参数,是传一个NotifyIconData的指针过去,
代码如下了
var
TrayIcon: NotifyIconData;
begin
TrayIcon.Wnd := handle; //窗口句柄
TrayIcon.uID := 500; //这个标志,当你处理这个发出的消息时,的一参数
TrayIcon.uFlags := NIF_MESSAGE+NIF_ICON+NIF_TIP;
{决定该结构中的有效部分,
如有NIF_MESSAGE则 uCallbackMessage参数有 效 ;
若有NIF_ICON 则hIcon有效;
有 NIF_TIP则 szTip参数有效,
当然你可 以让这三个参数都有效只须要在这个参数中写成
NIF_MESSAGE+NIF_ICON+NIF_TIP即可}
TrayIcon.uCallbackMessage := WM_USER + 10;
{当有动作在这个托盘时,发什么消息到窗口。 这里用的是自定义消息}
TrayIcon.hIcon := LoadIcon(0,'C:\\windows\\bzm.bmp'); //这个BMP图标的句柄
TrayIcon.cbSize := SizeOf(TrayIcon); //是这个结构的总长度 用SizeOf
TrayIcon.szTip := 'AAAAAA'; //设置在它下面的提示文字
Shell_NotifyIcon(NIM_ADD, @TrayIcon); //传指针时,在前面加上@,得到对象指针
------------------
事还没完,你要捕获你送出 WM_USER+10 的消息,在你这个TrayIcon.Wnd 窗口里。
在窗口事件里加入
procedure TrayOnMouse(var Msg: TMessage); message WM_User + 10;
下面是我程序里的处理函数
procedure TMainform.TrayOnMouse(var Msg: TMessage);
var
MouseXY : TPoint;
begin
case Msg.LParam of // Msg.LParam 便是具体消息参数,
// 还有一个Msg.RParam 参数就是TrayIcon.uID
WM_LBUTTONUP: Begin // 如果是WM_LBUTTONUP ,为鼠标右按下后放开
StuFaceForm.Show;//这里就可写你的程序了,,,
SetWindowPos(
StuFaceForm.Handle,
HWND_TOPMOST,
StuFaceForm.Left, StuFaceForm.Top,
StuFaceForm.Width, StuFaceForm.Height,
SWP_SHOWWINDOW
)
end;
WM_RBUTTONUP: begin
GetCursorPos(MouseXY);
PopupMenu.Popup(MouseXY.X, MouseXY.Y);
end;
end;
end;
一般来说让你的程序不在任务栏显示我目前知道的方法就是使用SetWindowLong函数来改变应用程序的显示风格
至于如何按下WIN+M组合键让APP缩小为一个图标,我个人认为主要的解决的问题是如何判断你当前按下了这个组合键。至于缩小为图标,这个方法是死的,就是一个结构,你填充后调用相应函数就可以了,具体可以在《Delphi 5开发指南》中找,有很详细的说明!
判断组合键是否被按下,你可以在程序的Initialization部分为程序添加热键,具体步骤如下:
(用到3个API函数)
BOOL RegisterHotKey(
HWND hWnd, //响应该热键的窗口句柄
Int ID, //该热键的唯一标识,使用GlobalAddAtom函数获取
UINT fsModifiers, //该热键的辅助按键
UINT VK //该热键的键值
);
为了得到唯一标识,我们还将用到另一个API函数
ATOM GlobalAddAtom(LPCTSTR lpString //自己设定的一个字符串);
因为我们还要在程序退出的时候,消除这个热键(因为这是个资源,所以必须释放,否则如果其他的程序无法使用), 所以需要声明一个全局变量:
HotKeyID: Integer;
第一步:
在Initialization中,加入以下代码
HotKeyID := GlobalAddAtom(//这放你的组合键) - $C000;
注: HotKeyId的合法取之范围是0x0000到0xBFFF之间, GlobalAddAtom函数得到的值
在0xC000到0xFFFF之间,所以减掉0xC000来满足调用要求。
第二步:
在上面的代码下面加入:
RegisterHotKey(Handle, HotKeyID, MOD_Win, VK_M);
热键的辅助按键包括Mod_Ctrl 、Mod_Alt、Mod_Shift,对于Windows兼容键盘还支持Windows键,即其键面上有Windows标志的那个键,其值为Mod_Win。
上面的代码注册了一个热键:MOD_WIN+M。注:handle是一个特殊的变量,它表示当前窗口的句柄。
这个函数你应该能句举一反三了吧。
原理:
一旦热键设置成功,在程序应用过程中如果有相应的键被按下,Windows系统都会给你的应
用程序发送一个消息WM_HOTKEY,不管你的应用程序是否为当前活动的。其中WM_HOTKEY消
息的格式为:
idHotKey = (int) wParam; // 该参数在设置系统级的热键有用,一般不予使用
fuModifiers = (UINT) LOWORD(lParam); //热键的辅助按键
uVirtKey = (UINT) HIWORD(lParam); //热键的键值
第三步:
注册了热键,就该写下响应代码了。
首先,在程序头部分的private段中加入声明 (作用是声明这个过程,和声明变量类似。
关于如何声明函数、过程,请请参考各自的帮助文件或其它资料):
procedure HotKeyDown(var Msg: Tmessage); message WM_HOTKEY;
然后在程序中加入如下代码:
procedure TForm1.HotKeyDown(var Msg: Tmessage);
begin
if (Msg.LparamLo = MOD_win) AND Msg.LParamHi = VK_M then // 假设热键为WIN+M
begin
end;
最后一步:
在窗口的close事件中加入
UnRegisterHotKey(handle, HotKeyId); //注销HotKey, 释放资源。
另外,在程序中使用这样的热键其实是不规范的,我不知道你用过一个练习英语听力的软件SITMAN没有,里面设置了好几个全局的热键,导致程序和其他程序发生冲突。所以我还是建议你少使用这种类型的热键!!!!
另外,M的虚拟键值你在去SDK HELP查查,我手头目前无法查到,所以你最好确认一下
把窗口的父窗口设置为桌面窗口应该可以。