shawind 发表于 2012-9-23 13:00:29

又查了下,WS_EX_TOOLWINDOW只是在创建时有效,如果想在运行途中随意修改,还是得用ShowWIndow
弄了个例子,创建时显示正常窗口,点击最小化时在任务栏中隐藏,同时在托盘中显示图标。左键双击托盘中的图标,窗口又恢复正常,同时删去托盘中的图标。

#include <windows.h>

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

char szClassName[] = "CodeBlocksWindowsApp";

unsigned int iconmessage = RegisterWindowMessage("IconNotify"); //托盘图标使用的消息

#define MYWM_ICON (WM_APP+100) //自定义的窗口消息

int WINAPI WinMain (HINSTANCE hThisInstance,
                  HINSTANCE hPrevInstance,
                  LPSTR lpszArgument,
                  int nCmdShow)
{
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;


    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);


    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;

    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;


    if (!RegisterClassEx (&wincl))
      return 0;


    hwnd = CreateWindowEx (
               0,
               szClassName,
               "Code::Blocks Template Windows App",
               WS_SYSMENU|WS_MINIMIZEBOX,
               CW_USEDEFAULT,
               CW_USEDEFAULT,
               544,
               375,
               HWND_DESKTOP,
               NULL,
               hThisInstance,
               NULL
         );


    ShowWindow (hwnd, nCmdShow);

    while (GetMessage (&messages, NULL, 0, 0))
    {

      TranslateMessage(&messages);

      DispatchMessage(&messages);
    }


    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    NOTIFYICONDATA nid;
    nid.cbSize = sizeof(NOTIFYICONDATA);
    nid.hWnd = hwnd;
    nid.uID = iconmessage;
    nid.uFlags = NIF_ICON|NIF_MESSAGE;
    nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    nid.uCallbackMessage = MYWM_ICON;

    switch (message)
    {
    case WM_SIZE:
      switch(wParam)
      {
      case SIZE_MINIMIZED:
            ShowWindow(hwnd, SW_HIDE); //从任务栏中隐藏
            Shell_NotifyIcon(NIM_ADD, &nid); //显示托盘图标
            break;
      }
      break;

    case MYWM_ICON:
      if(wParam == iconmessage)
      {
            switch(lParam)
            {
            case WM_LBUTTONDBLCLK:
                ShowWindow(hwnd, SW_SHOWNORMAL); //重新在任务栏中显示
                Shell_NotifyIcon(NIM_DELETE, &nid); //删除托盘图标
                break;
            }
      }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

secondsen 发表于 2012-9-25 18:01:40

按照两位的指点捣鼓出来了

secondsen 发表于 2012-9-26 17:00:09

WY的代码,有一段MMX的alphablend


    __asm
    {
        mov            edi, pDstBmp        ; 目的像素
        mov            esi, pSrcBmp        ; 源像素
        xor            ebx, ebx            ; 已混合的高度
        mov            ecx, blend_width    ; 要混合的宽度                                 <-------------------------------ecx记录一行的长度

BLEND_BEGIN:
        cmp            dword ptr, 0x00FFFFFF    ; 如果alpha为0,则跳过混合部分
        jna            BLEND_END

        movd        mm0,             ; 把目的像素值移入mm0寄存器的低32位
        movd        mm1,             ; 把源像素值移入mm1寄存器的低32位

        ; Core Begin
        pxor        mm2, mm2            ; 把MM2清0
        punpcklbw    mm0, mm2            ; src:8 bit到16 bit以容纳结果,32bit expand to 64 bit
        punpcklbw    mm1, mm2            ; dst:8 bit到16 bit以容纳结果.32bit expand to 64 bit
        movq        mm3, mm1            ; 因为要用dst的Alpha值
        punpckhwd    mm3, mm3            ; 高字移动到双字
        punpckhdq    mm3, mm3            ; 双字移动到四字,现在有八个像素的Alpha了!
        movq        mm4, mm0            ; mm4 = dst
        movq        mm5, mm1            ; mm5 = src
        psubusw        mm4, mm1            ; dst-src,饱和减,小于0为0
        psubusw        mm5, mm0            ; src-dst,饱和减,小于0为0
        pmullw        mm4, mm3            ; Alpha * (src-dst)
        pmullw        mm5, mm3            ; Alpha * (dst-src)
        psrlw        mm4, 8                ; 除以256,now mm4 get the result,(src-dst)<0 部分
        psrlw        mm5, 8                ; 除以256,now mm5 get the result,(dst-src)>0 部分
        paddusw        mm0, mm5            ; 饱和加到原图象:D=Alpha*(O-S)+S,(src-dst)<0 部分
        psubusw        mm0, mm4            ; 饱和加到原图象D=S-Alpha*(S-O),(dst-src)>0 部分
        packuswb    mm0, mm0            ; 紧缩到低32bit
        ; Core End

        movd        , mm0            ; 混合结果写进目的像素

BLEND_END:
        add            edi, 4
        add            esi, 4
        loop        BLEND_BEGIN                ; 循环                                          <--------------------------------------------跳回去循环,前面没有ecx 的cmp,jxx为啥没有死循环哇??

        add            esi, nextLineOffset_src    ; 加上偏移量,使定位到下行起始处
        add            edi, nextLineOffset_dst

        inc            ebx
        mov            ecx, blend_width

        cmp            ebx, blend_height        ; 若ebx小于blend_height,则转移到上面继续混合
        jb            BLEND_BEGIN

        EMMS                                ; 因为从mm0到mm7,这些寄存器是“借用”浮点寄存器的低64位,所以每次在用完MMX指令后一定要用EMMS指令将寄存器清空
    }

weiwuyuan 发表于 2012-9-28 22:53:53

引用第12楼secondsen于2012-09-26 17:00发表的 :
WY的代码,有一段MMX的alphablend
.......   


loop指令等于:
if (--ecx > 0)
jmp 标号

另外,mmx汇编指令太过烦琐,做点小工具不用也罢,用纯C写就很容易明白了:

void AlphaBlend32(UINT* pDstBmp, int dst_width, UINT* pSrcBmp, int src_width, int blend_width, int blend_height)
{
// C实现
{
const int nextLineOffset_src = (src_width - blend_width) * 4; // 混合完一行像素后,通过加上该值,便可直接定位到下行起始像素
const int nextLineOffset_dst = (dst_width - blend_width) * 4;
BYTE* pSrc = (BYTE*)pSrcBmp;
BYTE* pDst = (BYTE*)pDstBmp;
int below_A, below_R, below_G, below_B;
int above_A, above_R, above_G, above_B;
for (int h=0, w=0; h<blend_height; h++)
{
   for (w=0; w<blend_width; w++)
   {
    above_B = *pSrc++;
    above_G = *pSrc++;
    above_R = *pSrc++;
    above_A = *pSrc++;
    if (above_A == 0)
    {
   pDst += 4;
   continue;
    }
    below_B = *pDst;
    below_G = *(pDst+1);
    below_R = *(pDst+2);
    below_A = *(pDst+3);
    *pDst++ = below_B - (below_B-above_B)*above_A/255;
    *pDst++ = below_G - (below_G-above_G)*above_A/255;
    *pDst++ = below_R - (below_R-above_R)*above_A/255;
    if (below_A == 255)
   *pDst++ = 255;
    else
   *pDst++ = below_A - (below_A-above_A)*above_A/255;
   }
   pSrc += nextLineOffset_src;
   pDst += nextLineOffset_dst;
}
}
}

secondsen 发表于 2012-10-5 18:08:42

WY的程序,托盘的菜单,右击出现之后,点击桌面,菜单也不消失啊??
页: 1 [2]
查看完整版本: windows XP下,我想自己弄个桌面widget可以不?