secondsen 发表于 2012-9-21 17:14:55

windows XP下,我想自己弄个桌面widget可以不?

RT。。。

其实桌面工具就是自己做个窗口把??是不是这样哇?

想用wxWidget做,边学习边制作。。。

那么再有个问题。。。最小化到托盘怎么做?打开程序,托盘那里就多出个图标,最小化,任务栏就没有他,只能双击托盘图标才能出来,托盘图标也能右键菜单之类的,这个一直不会。。。

shawind 发表于 2012-9-21 18:12:56

可以,这里面最有名的应用程序叫“伪春菜”。你google一下,就可以看多很多的有爱人士的无聊之作。

那么再有个问题。。。最小化到托盘怎么做?

在消息处理回调函数里,处理WM_SIZE消息就可以判断窗口是否已经最小化,具体用法google之

打开程序,托盘那里就多出个图标,

winapi函数Shell_NotifyIcon是用来创建,修改,删除托盘图标的。具体用法google之

最小化,任务栏就没有他,

不显示在任务栏,用SetWindowLong将应用程序窗口的风格改成WS_EX_TOOLWINDOW。 具体用法google之

只能双击托盘图标才能出来,托盘图标也能右键菜单之类的

定义一个自己的消息
unsigned int icon_message;
在消息循环处理中
WndProc(...)
{
       if(Message.Msg == icon_message)
       {
              if(Message.LParam == WM_LBUTTONDBLCLK)  //左键双击的消息
              {
                  .....
               }
       }
}
嘛,这些东西网上讲得很多。于是,惯例。具体google之。

weiwuyuan 发表于 2012-9-21 18:17:46

没有什么东西是win32 api不能实现的,所以最好不要用别人的工具,除非你很了解你所用的工具是怎么实现的.
你所说的桌面工具是不是类似迅雷的桌面图标? 这个可以用SetDIBitsToDevice() + UpdateLayeredWindow()实现
系统托盘也不麻烦,我前段时间写过一个应用.我给你弄段关键代码:

// 创建系统托盘
void CreateSystemTray(NOTIFYICONDATAA* pOutIconData, HWND hWnd, UINT hIconID, UINT user_msg)
{
assert(pOutIconData != NULL);
memset(pOutIconData, 0, sizeof(NOTIFYICONDATAA));
HINSTANCE hInstance = (HINSTANCE)::GetWindowLong(hWnd, GWL_HINSTANCE);
pOutIconData->cbSize = sizeof(NOTIFYICONDATAA);
pOutIconData->hWnd = hWnd;
pOutIconData->uID = hIconID;
pOutIconData->uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
pOutIconData->uCallbackMessage = user_msg; // WM_USER
pOutIconData->hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(hIconID));
}
// 设置/隐藏系统托盘
BOOL SetSystemTray(NOTIFYICONDATAA* pIconData, bool bShow=true)
{
assert(pIconData != NULL);
BOOL bOK = FALSE;
if (bShow)
bOK = Shell_NotifyIconA(NIM_ADD, pIconData);
else
bOK = Shell_NotifyIconA(NIM_DELETE, pIconData);
return bOK;
}

用法示例:
#define WM_USER_TRAY WM_USER+1
#define IDM_OPEN1
#define IDM_EXIT2
NOTIFYICONDATAAg_IconData;
HMENU    g_hPopupMenu;

// 创建系统托盘
CreateSystemTray(&g_IconData, hWnd, IDI_ICON1, WM_USER_TRAY);

// 创建系统托盘右键弹出菜单
g_hPopupMenu = CreatePopupMenu();
AppendMenuA(g_hPopupMenu, MF_STRING, IDM_OPEN, "打开");
AppendMenuA(g_hPopupMenu, MF_STRING, IDM_EXIT, "退出");


// 窗口函数部分处理
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_LBUTTONDOWN:
// 使鼠标单击窗口任何一个地方都能移动整个窗口
::SendMessageA(hWnd, WM_SYSCOMMAND, 0xF012, 0);
break;
case WM_SIZE:
{
   switch (wParam)
   {
   case SIZE_MINIMIZED: // 这里通过点击最小化来设置系统托盘
    {
   SetSystemTray(&g_IconData); // 设置系统托盘
   ShowWindow(hWnd, SW_HIDE);
    }
    break;
   }
}
break;
case WM_COMMAND:
{
   WORD hWord = HIWORD(wParam);
   WORD lWord = LOWORD(wParam);
   switch(lWord)
   {
   case IDM_OPEN:
    {
   // 隐藏系统托盘
   SetSystemTray(&g_IconData, false);
   ShowWindow(hWnd, SW_SHOW);
   SendMessageA(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
    }
    break;
   case IDM_EXIT:
    PostQuitMessage(0);
    break;
   }
}
break;
case WM_USER_TRAY:
{
   UINT msg = (UINT)lParam;
   UINT id = (UINT)wParam;
   if (id == IDI_ICON1)
   {
    // 左键单击就隐藏系统托盘,并显示窗口
    if (msg == WM_LBUTTONDOWN)
    {
   // 隐藏系统托盘
   SetSystemTray(&g_IconData, false);
   ShowWindow(hWnd, SW_SHOW);
   SendMessageA(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
    }
    // 右键单击后弹出菜单
    if (msg == WM_RBUTTONDOWN)
    {
   POINT pos;
   ::GetCursorPos(&pos);
   TrackPopupMenu(g_hPopupMenu, TPM_RIGHTALIGN, pos.x, pos.y, NULL, hWnd, NULL);
    }
   }
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


另外,关于不规则半透明窗口请参见:
http://blog.csdn.net/weiwuyuan/article/details/8005090


示例程序(vs2008):
http://www.newmuhon.com/files/desktopTool.rar

secondsen 发表于 2012-9-21 19:49:55

LS两位真是好人,此刻我热泪盈眶


MFC我都不喜欢,怎么可能喜欢别人写的东西。这是什么样的执念啊。。。瓦咔咔!

weiwuyuan 发表于 2012-9-22 01:16:10

弄了张多窗口的图,效果不错.

secondsen 发表于 2012-9-22 18:24:10

#include <windows.h>

LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    }

    //调用缺省消息处理过程
    //窗口处理消息中,系统提供一个默认消息处理函数
    //做没有写出来的消息交给这个函数处理
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

#define App_width 800
#define App_height 600

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
    // 信息提示框
    /*MessageBox(
        NULL,       // 默认的窗口句柄
        "窗口程序", // 信息框的内容
        "提示信息", // 信息的标题
        MB_YESNO);*/
    // 创建窗口的过程:
    // 1.创建窗口类,需要赋值
    WNDCLASS wc;
    wc.hInstance     = hInst;                                // 设置当前进程句柄
    wc.lpszClassName = TEXT("2nDs_Desktop_Widget");            // 注册名字
    wc.lpfnWndProc     = WinProc;                                // 设置当前窗口的信息处理函数
    wc.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;// 窗口类的风格
    wc.hIcon         = NULL;                                // 光标的设置
    wc.hCursor         = LoadCursor(NULL, IDC_ARROW);            // 设置箭头光标
    wc.lpszMenuName  = NULL;                                // 设置菜单(无菜单)
    wc.cbClsExtra    = 0;                                    // 类的扩展字节数
    wc.cbWndExtra    = 0;                                    // 窗口的扩展字节数
    wc.hbrBackground = HBRUSH(GetStockObject(BLACK_BRUSH));    // 窗口背景的颜色
    
    // 2.注册窗口类
    if(!RegisterClass(&wc)) // 取地址
    {
        MessageBox( NULL, TEXT("注册窗口类出错!"), TEXT("RegisterClass"), MB_OK) ;
        return NULL;
    }

    // 3.创建窗口,定义窗口句柄
    //窗口模式
    HWND hWnd = CreateWindow(TEXT("2nDs_Desktop_Widget"),
        TEXT("2nDs_Desktop_Widget"),
        WS_POPUP | WS_SYSMENU | WS_VISIBLE,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInst,
        NULL);

    if(hWnd == NULL)
    {
        MessageBox( NULL, TEXT("创建窗口出错!"), TEXT("CreateWindow"), MB_OK);
        return NULL;
    }

    // 获取系统屏幕大小
    int    Win_W = GetSystemMetrics(SM_CXSCREEN);
    int Win_H = GetSystemMetrics(SM_CYSCREEN);
    // 求出窗口居于屏幕中央时的左上角位置
    int x1 = (Win_W - App_width) / 2;
    int y1 = (Win_H - App_height) / 2 - 32;
    // 根据上面的值,调整窗口的位置
    SetWindowPos(hWnd, HWND_NOTOPMOST,
        x1, y1, App_width, App_height,
        SWP_HIDEWINDOW);
    // 获取客户区的相对于屏幕左上角的位置
    RECT rectWin;
    GetClientRect(hWnd, &rectWin);
    ClientToScreen(hWnd, (LPPOINT)&rectWin);
    ClientToScreen(hWnd, (LPPOINT)&rectWin + 1);

    // 4.显示窗口
    ShowWindow(hWnd, SW_NORMAL); // 显示模式

    // 窗口半透明
    SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE)|WS_EX_LAYERED);
    SetLayeredWindowAttributes(hWnd,0,(255*70)/150,LWA_ALPHA);

    // 5.更新窗口
    UpdateWindow(hWnd);
    
    //6.消息循环
    MSG  msg;    msg.message = WM_NULL;//存储消息结构体
    //1.消息类型 : 1)命令消息 按钮
    //               2)非命令消息 键盘、鼠标消息
    //2.消息的附加消息:存储消息中的相关不同信息值
    // typedef struct tagMSG {
    //HWND hwnd;
    //UINT message;
    //WPARAM wParam; //消息的附加消息
    //LPARAM lParam; //消息的附加消息
    //DWORD time; //符号长整型 当前时间
    //POINT pt; } //存储点的,鼠标的位置
    //MSG;
    //1.第二个参数是窗口句柄,如果传hWnd,说明要过滤消息
    // 如果传NULL,说明处理所有的消息,后面两个参数为0
    // 有消息就处理,没有消息就等待。
    while(msg.message != WM_QUIT)
    {
        //if( GetMessage(&msg,NULL,0,0) )
        if (PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
        {
            //解析消息
            TranslateMessage(&msg);
            //分派消息
            DispatchMessage(&msg);
        }
    }

    //7.注销窗口类
    UnregisterClass(TEXT("2nDs_Desktop_Widget"),  // 窗口类名字
                    hInst); // 进程句柄

    return (int)msg.wParam;
}


半透明桌面,没有标题栏。不出现任务栏还是不会弄T_T



还有 Alt+Tab和ALT+CTRL+DELETE都看不到这个程序,进程能看到怎么整哇?



就是整个程序就是迅雷的浮动窗口那样,或者是360显示流量的浮动窗口那样

secondsen 发表于 2012-9-22 18:31:36

WY那个程序 我用2010编译,显示找不到main.exe
原来名字是main_D.exe我再看看去

weiwuyuan 发表于 2012-9-22 20:23:16

引用第5楼secondsen于2012-09-22 18:24发表的 :
#include <windows.h>

LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
....... http://www.rpgchina.net/images/back.gif


1:我那程序写的很明白了
2:不想在任务栏显示程序,可以这样子:
CreateWindowExA(WS_EX_LAYERED|WS_EX_TOOLWINDOW, ....);
3:不要标题栏,窗口style就填:WS_POPUP | WS_MINIMIZEBOX | WS_SYSMENU
4:SetLayeredWindowAttributes()函数只能指定一个全局透明度的窗口,而无法实现不规则半透明的窗口,就是你无法用一张带有alpha渐变的图去做窗口背景.
5:你给的代码因为没有绘制图像,所以没办法测试不规则半透明窗口,我给出的代码,已经能够实现你所需要的所有功能了.

secondsen 发表于 2012-9-22 22:53:33

style 只是WS_EX_LAYERED|WS_EX_TOOLWINDOW为啥任务栏还是有显示哇?

weiwuyuan 发表于 2012-9-22 23:16:27

引用第8楼secondsen于2012-09-22 22:53发表的 :
style 只是WS_EX_LAYERED|WS_EX_TOOLWINDOW为啥任务栏还是有显示哇? http://www.rpgchina.net/images/back.gif


具体原因不清楚,我一直都是在创建的时候,指定这个属性,
就是在窗口还未显示的时候设置这个属性是没问题的
页: [1] 2
查看完整版本: windows XP下,我想自己弄个桌面widget可以不?