弄了个例子,创建时显示正常窗口,点击最小化时在任务栏中隐藏,同时在托盘中显示图标。左键双击托盘中的图标,窗口又恢复正常,同时删去托盘中的图标。
#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;
}
按照两位的指点捣鼓出来了 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指令将寄存器清空
} 引用第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;
}
}
}
WY的程序,托盘的菜单,右击出现之后,点击桌面,菜单也不消失啊??
页:
1
[2]