正在开发中的游戏有个全屏功能--可以在window桌面背景上运行,就像一些视频播放器在桌面背景上播放一样的,花了个上午整了个Demo放出来留个纪念。

实现功能:显示图标,双击图标执行相应的程序,右击图标弹出该图标对应得菜单,点击非图标区则弹出桌面菜单。需要完整工程可以点此下载:DesktopWindow.rar。程序效果图如下:

模拟window桌面实现

在这个程序里,定义了一个XShellItem的数据结构,保持桌面图标的iten id(ITEMIDLiST),图标以及文字图标。

模拟window桌面实现模拟window桌面实现structXShellItem...{
模拟window桌面实现ITEMIDLIST
*itemId;
模拟window桌面实现
模拟window桌面实现
intx;
模拟window桌面实现
inty;
模拟window桌面实现
intw;
模拟window桌面实现
inth;
模拟window桌面实现
模拟window桌面实现
intnameX;
模拟window桌面实现
intnameY;
模拟window桌面实现
intnameW;
模拟window桌面实现
intnameH;
模拟window桌面实现
模拟window桌面实现BOOLhit;
模拟window桌面实现
模拟window桌面实现CStringWname;
模拟window桌面实现Bitmap
*icon;
模拟window桌面实现Bitmap
*nameIcon;
模拟window桌面实现
模拟window桌面实现XShellItem()
模拟window桌面实现:
模拟window桌面实现itemId(NULL),
模拟window桌面实现x(
0),
模拟window桌面实现y(
0),
模拟window桌面实现w(
0),
模拟window桌面实现h(
0),
模拟window桌面实现nameX(
0),
模拟window桌面实现nameY(
0),
模拟window桌面实现nameW(
0),
模拟window桌面实现nameH(
0),
模拟window桌面实现name(L
""),
模拟window桌面实现hit(FALSE),
模拟window桌面实现icon(NULL),
模拟window桌面实现模拟window桌面实现nameIcon(NULL)
...{
模拟window桌面实现}

模拟window桌面实现模拟window桌面实现
~XShellItem()...{
模拟window桌面实现}

模拟window桌面实现}
;

然后定义一个数组CAtlArray<XShellItem> itemArray;用来保存所有桌面图标对象,在InitShellFolder()中对它进行初始化:

模拟window桌面实现//获取桌面图标的相关数据
模拟window桌面实现
BOOLInitShellFolder()
模拟window桌面实现模拟window桌面实现
...{
模拟window桌面实现HRESULThRslt
=SHGetDesktopFolder(&folder);
模拟window桌面实现模拟window桌面实现
if(FAILED(hRslt))...{
模拟window桌面实现
returnFALSE;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现CComPtr
<IEnumIDList>ids;
模拟window桌面实现hRslt
=folder->EnumObjects(0,SHCONTF_FOLDERS|SHCONTF_NONFOLDERS,&ids);
模拟window桌面实现模拟window桌面实现
if(FAILED(hRslt))...{
模拟window桌面实现
returnFALSE;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现CAtlList
<XShellItem>items;
模拟window桌面实现模拟window桌面实现
for(;;)...{
模拟window桌面实现ITEMIDLIST
*id=0;
模拟window桌面实现ULONGcIds
=0;
模拟window桌面实现
模拟window桌面实现hRslt
=ids->Next(1,&id,&cIds);
模拟window桌面实现模拟window桌面实现
if(hRslt!=S_OK)...{
模拟window桌面实现
break;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现CStringWname;
模拟window桌面实现模拟window桌面实现STRRETstr
=...{0};
模拟window桌面实现hRslt
=folder->GetDisplayNameOf(id,SHGDN_NORMAL|SHGDN_INFOLDER,&str);
模拟window桌面实现模拟window桌面实现
if(SUCCEEDED(hRslt))...{
模拟window桌面实现LPWSTRpname
=0;
模拟window桌面实现StrRetToStrW(
&str,id,&pname);
模拟window桌面实现name
=pname;
模拟window桌面实现CoTaskMemFree(pname);
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现XShellItemitem;
模拟window桌面实现
模拟window桌面实现item.itemId
=id;
模拟window桌面实现item.name
=name;
模拟window桌面实现items.AddTail(item);
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现SIZE_TiItem
=0;
模拟window桌面实现SIZE_TcItems
=items.GetCount();
模拟window桌面实现
模拟window桌面实现itemArray.SetCount(cItems);
模拟window桌面实现
模拟window桌面实现POSITIONpos
=items.GetHeadPosition();
模拟window桌面实现模拟window桌面实现
while(pos!=0)...{
模拟window桌面实现XShellItem
&si=items.GetNext(pos);
模拟window桌面实现itemArray[iItem]
=si;
模拟window桌面实现iItem
++;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现HDChDC
=CreateCompatibleDC(0);
模拟window桌面实现
模拟window桌面实现Graphicsg(hDC);
模拟window桌面实现g.Clear(Color(
0,0,0,0));
模拟window桌面实现
模拟window桌面实现模拟window桌面实现ICONMETRICSim
=...{0};
模拟window桌面实现im.cbSize
=sizeof(im);
模拟window桌面实现SystemParametersInfo(SPI_GETICONMETRICS,
sizeof(im),&im,0);
模拟window桌面实现
模拟window桌面实现SolidBrushbr_t(Color(
255,255,255));
模拟window桌面实现Fontfont_i(hDC,
&(im.lfFont));
模拟window桌面实现
floatfcy=font_i.GetHeight(&g)*2+2;
模拟window桌面实现DeleteDC(hDC);
模拟window桌面实现
模拟window桌面实现Gdiplus::StringFormatsf(Gdiplus::StringFormat::GenericTypographic());
模拟window桌面实现sf.SetAlignment(Gdiplus::StringAlignmentCenter);
模拟window桌面实现sf.SetTrimming(Gdiplus::StringTrimmingEllipsisWord);
模拟window桌面实现
模拟window桌面实现iconSpacingWidth
=im.iHorzSpacing+OFFSET_WIDTH;
模拟window桌面实现iconSpacingHeight
=im.iVertSpacing+OFFSET_HEIGHT;
模拟window桌面实现
模拟window桌面实现
inticonWidth=GetSystemMetrics(SM_CXICON);
模拟window桌面实现
inticonHeight=GetSystemMetrics(SM_CYICON);
模拟window桌面实现
模拟window桌面实现模拟window桌面实现
for(SIZE_Ti=0;i<cItems;i++)...{
模拟window桌面实现XShellItem
&item=itemArray[i];
模拟window桌面实现
模拟window桌面实现
//SHGetFileInfo
模拟window桌面实现
HICONhIcon=0;
模拟window桌面实现HIMAGELISThImgList;
模拟window桌面实现SHFILEINFOstSHFileInfo;
模拟window桌面实现CImageListcImgList;
模拟window桌面实现
模拟window桌面实现
//获取图标
模拟window桌面实现
hImgList=(HIMAGELIST)::SHGetFileInfo(
模拟window桌面实现(LPCWSTR)item.itemId,
模拟window桌面实现
0,
模拟window桌面实现
&stSHFileInfo,
模拟window桌面实现
sizeof(SHFILEINFO),
模拟window桌面实现SHGFI_PIDL
|SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX);
模拟window桌面实现
模拟window桌面实现
//DIBSection8bit
模拟window桌面实现
BITMAPINFObmi;
模拟window桌面实现BITMAPINFOHEADER
&bmih=bmi.bmiHeader;
模拟window桌面实现bmih.biSize
=sizeof(bmih);
模拟window桌面实现bmih.biWidth
=ICON_WIDTH;
模拟window桌面实现bmih.biHeight
=-ICON_HEIGHT;//BMP反转
模拟window桌面实现
bmih.biPlanes=1;
模拟window桌面实现bmih.biBitCount
=32;
模拟window桌面实现bmih.biCompression
=BI_RGB;
模拟window桌面实现bmih.biSizeImage
=0;
模拟window桌面实现bmih.biXPelsPerMeter
=0;
模拟window桌面实现bmih.biYPelsPerMeter
=0;
模拟window桌面实现bmih.biClrUsed
=0;
模拟window桌面实现bmih.biClrImportant
=0;
模拟window桌面实现
模拟window桌面实现HDCmemDC
=CreateCompatibleDC(0);
模拟window桌面实现
void*pDib=0;
模拟window桌面实现HBITMAPhBmp
=CreateDIBSection(memDC,&bmi,DIB_RGB_COLORS,&pDib,0,0);
模拟window桌面实现GdiFlush();
模拟window桌面实现
模拟window桌面实现HGDIOBJold
=SelectObject(memDC,hBmp);
模拟window桌面实现
模拟window桌面实现
//ImageList_DrawWindowsXP
模拟window桌面实现
ImageList_SetBkColor(hImgList,0x0);
模拟window桌面实现ImageList_Draw(hImgList,stSHFileInfo.iIcon,memDC,
0,0,ILD_NORMAL);
模拟window桌面实现SelectObject(memDC,old);
模拟window桌面实现DeleteDC(memDC);
模拟window桌面实现
模拟window桌面实现cImgList.Attach(hImgList);
模拟window桌面实现hIcon
=cImgList.ExtractIcon(stSHFileInfo.iIcon);
模拟window桌面实现cImgList.Detach();
模拟window桌面实现
模拟window桌面实现模拟window桌面实现
if(hIcon!=0)...{
模拟window桌面实现
模拟window桌面实现
//Bitmap::FromHICON0~255
模拟window桌面实现
item.icon=Bitmap::FromHICON(hIcon);
模拟window桌面实现item.w
=iconWidth;
模拟window桌面实现item.h
=iconHeight;
模拟window桌面实现
模拟window桌面实现Gdiplus::RectFrc(
float(2),float(2),float(iconSpacingWidth-4),fcy);
模拟window桌面实现
模拟window桌面实现Gdiplus::Bitmap
*nameIcon=newBitmap(NAME_WIDTH,NAME_HEIGHT,&g);
模拟window桌面实现Gdiplus::Graphics
*g2=Gdiplus::Graphics::FromImage(nameIcon);
模拟window桌面实现g2
->Clear(Gdiplus::Color(Gdiplus::ARGB(0)));
模拟window桌面实现
模拟window桌面实现g2
->DrawString(item.name,item.name.GetLength(),&font_i,rc,&sf,&br_t);
模拟window桌面实现
模拟window桌面实现item.nameIcon
=nameIcon;
模拟window桌面实现item.nameW
=NAME_WIDTH;
模拟window桌面实现item.nameH
=NAME_HEIGHT;
模拟window桌面实现
模拟window桌面实现deleteg2;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现DestroyIcon(hIcon);
模拟window桌面实现DeleteObject(hBmp);
模拟window桌面实现DestroyIcon(stSHFileInfo.hIcon);
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现
returnTRUE;
模拟window桌面实现}

注意这里面并没有设置图标对象的位置,因为当窗口改变大小的时候,相应地也要调整图标的描绘位置,所以图标位置是在SetShellItemPosition()中动态调整的.

模拟window桌面实现//根据窗口大小设置图标位置
模拟window桌面实现
voidSetShellItemPosition()
模拟window桌面实现模拟window桌面实现
...{
模拟window桌面实现
inticonWidth=GetSystemMetrics(SM_CXICON);
模拟window桌面实现
inticonHeight=GetSystemMetrics(SM_CYICON);
模拟window桌面实现
staticconstintOFFSET_Y=20;
模拟window桌面实现
intx=0;
模拟window桌面实现
inty=OFFSET_Y;
模拟window桌面实现SIZE_TcItems
=itemArray.GetCount();
模拟window桌面实现模拟window桌面实现
for(SIZE_Ti=0;i<cItems;i++)...{
模拟window桌面实现XShellItem
&item=itemArray[i];
模拟window桌面实现模拟window桌面实现
if(item.icon)...{
模拟window桌面实现item.x
=x+(iconSpacingWidth-iconWidth)/2;
模拟window桌面实现item.y
=y;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现模拟window桌面实现
if(item.nameIcon)...{
模拟window桌面实现item.nameX
=x;
模拟window桌面实现item.nameY
=y+iconHeight+2;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现WTL::CRectrect;
模拟window桌面实现GetClientRect(
&rect);
模拟window桌面实现y
+=iconSpacingHeight;
模拟window桌面实现模拟window桌面实现
if(y+iconSpacingHeight>=rect.bottom)...{
模拟window桌面实现x
+=iconSpacingWidth;
模拟window桌面实现y
=OFFSET_Y;
模拟window桌面实现}

模拟window桌面实现}

模拟window桌面实现}

描绘图标就很简单了,呵呵,不贴了,下面来说说弹出图标菜单,执行图标对应的程序以及弹出桌面菜单。

执行图标对应的程序,需要以先前保持的图标itemid作为参数,代码如下:

模拟window桌面实现voidRunShellItem(ITEMIDLIST*pIID)
模拟window桌面实现模拟window桌面实现
...{
模拟window桌面实现SHELLEXECUTEINFOinfo;
模拟window桌面实现info.cbSize
=sizeof(SHELLEXECUTEINFO);
模拟window桌面实现info.fMask
=SEE_MASK_INVOKEIDLIST;
模拟window桌面实现info.hwnd
=m_hWnd;
模拟window桌面实现info.lpVerb
=NULL;
模拟window桌面实现info.lpFile
=NULL;
模拟window桌面实现info.lpParameters
=NULL;
模拟window桌面实现info.lpDirectory
=NULL;
模拟window桌面实现info.nShow
=SW_SHOWNORMAL;
模拟window桌面实现info.hInstApp
=NULL;
模拟window桌面实现info.lpIDList
=pIID;
模拟window桌面实现ShellExecuteEx(
&info);
模拟window桌面实现}

弹出桌面菜单的代码如下:

模拟window桌面实现//桌面菜单
模拟window桌面实现
voidDesktopMenu()
模拟window桌面实现模拟window桌面实现
...{
模拟window桌面实现HWNDprogram
=FindWindowEx(0,0,_T("Progman"),_T("ProgramManager"));
模拟window桌面实现HWNDview
=FindWindowEx(program,0,_T("SHELLDLL_DefView"),0);
模拟window桌面实现
模拟window桌面实现
//HWNDlist=FindWindowEx(view,0,_T("SysListView32"),0);
模拟window桌面实现
::SetForegroundWindow(view);
模拟window桌面实现
模拟window桌面实现POINTpt;
模拟window桌面实现GetCursorPos(
&pt);
模拟window桌面实现
模拟window桌面实现LPARAMlp
=pt.y<<16|(pt.x-32);
模拟window桌面实现::PostMessage(view,WM_LBUTTONDOWN,
0,lp);
模拟window桌面实现::PostMessage(view,WM_RBUTTONUP,
0,lp);
模拟window桌面实现}

弹出图标菜单的代码如下,这里定义了两个全局的IContextMenu对象:
static IContextMenu2* g_pIContext2 = NULL;
static IContextMenu3* g_pIContext3 = NULL;

以便在消息回调函数中使用。具体代码如下:

模拟window桌面实现//图标菜单
模拟window桌面实现
voidRightMenu(ITEMIDLIST*pIID)
模拟window桌面实现模拟window桌面实现
...{
模拟window桌面实现HWNDhwnd
=m_hWnd;
模拟window桌面实现
模拟window桌面实现LPCONTEXTMENUpContextMenu
=NULL;
模拟window桌面实现LPCONTEXTMENUpCtxMenuTemp
=NULL;
模拟window桌面实现
模拟window桌面实现g_pIContext2
=NULL;
模拟window桌面实现g_pIContext3
=NULL;
模拟window桌面实现
模拟window桌面实现
intmenuType=0;
模拟window桌面实现
模拟window桌面实现HRESULThRslt
=folder->GetUIObjectOf(
模拟window桌面实现hwnd,
模拟window桌面实现
1,
模拟window桌面实现(LPCITEMIDLIST
*)&(pIID),
模拟window桌面实现IID_IContextMenu,
模拟window桌面实现
0,
模拟window桌面实现(
void**)&pCtxMenuTemp);
模拟window桌面实现模拟window桌面实现
if(FAILED(hRslt))...{
模拟window桌面实现
return;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现POINTpt;
模拟window桌面实现GetCursorPos(
&pt);
模拟window桌面实现
模拟window桌面实现模拟window桌面实现
if(pCtxMenuTemp->QueryInterface(IID_IContextMenu3,(void**)&pContextMenu)==NOERROR)...{
模拟window桌面实现menuType
=3;
模拟window桌面实现}

模拟window桌面实现模拟window桌面实现
elseif(pCtxMenuTemp->QueryInterface(IID_IContextMenu2,(void**)&pContextMenu)==NOERROR)...{
模拟window桌面实现menuType
=2;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现模拟window桌面实现
if(pContextMenu)...{
模拟window桌面实现pCtxMenuTemp
->Release();
模拟window桌面实现}

模拟window桌面实现模拟window桌面实现
else...{
模拟window桌面实现pContextMenu
=pCtxMenuTemp;
模拟window桌面实现menuType
=1;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现模拟window桌面实现
if(menuType==0)...{
模拟window桌面实现
return;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现HMENUhMenu
=CreatePopupMenu();
模拟window桌面实现hRslt
=pContextMenu->QueryContextMenu(hMenu,0,1,0x7fff,CMF_NORMAL|CMF_EXPLORE);
模拟window桌面实现模拟window桌面实现
if(FAILED(hRslt))...{
模拟window桌面实现
return;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现#ifndef_WIN64
模拟window桌面实现
#pragmawarning(disable:42444311)
模拟window桌面实现
#endif
模拟window桌面实现
模拟window桌面实现
//subclasswindow
模拟window桌面实现
WNDPROColdWndProc=NULL;
模拟window桌面实现模拟window桌面实现
if(menuType>1)...{
模拟window桌面实现
模拟window桌面实现
//onlysubclassifitisIID_IContextMenu2orIID_IContextMenu3
模拟window桌面实现
oldWndProc=(WNDPROC)SetWindowLongPtr(GWL_WNDPROC,(LONG)HookWndProc);
模拟window桌面实现模拟window桌面实现
if(menuType==2)...{
模拟window桌面实现g_pIContext2
=(LPCONTEXTMENU2)pContextMenu;
模拟window桌面实现}

模拟window桌面实现模拟window桌面实现
else...{
模拟window桌面实现g_pIContext3
=(LPCONTEXTMENU3)pContextMenu;
模拟window桌面实现}

模拟window桌面实现}

模拟window桌面实现模拟window桌面实现
else...{
模拟window桌面实现oldWndProc
=NULL;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现
intcmd=::TrackPopupMenu(
模拟window桌面实现hMenu,
模拟window桌面实现TPM_LEFTALIGN
|TPM_BOTTOMALIGN|TPM_RETURNCMD|TPM_LEFTBUTTON,
模拟window桌面实现pt.x,
模拟window桌面实现pt.y,
模拟window桌面实现
0,
模拟window桌面实现hwnd,
模拟window桌面实现
0);
模拟window桌面实现
模拟window桌面实现
//unsubclass
模拟window桌面实现模拟window桌面实现
if(oldWndProc)...{
模拟window桌面实现SetWindowLongPtr(GWL_WNDPROC,(LONG)oldWndProc);
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现#ifndef_WIN64
模拟window桌面实现
#pragmawarning(default:42444311)
模拟window桌面实现
#endif
模拟window桌面实现模拟window桌面实现
if(cmd!=0)...{
模拟window桌面实现模拟window桌面实现CMINVOKECOMMANDINFOci
=...{0};
模拟window桌面实现ci.cbSize
=sizeof(CMINVOKECOMMANDINFO);
模拟window桌面实现ci.hwnd
=hwnd;
模拟window桌面实现ci.lpVerb
=(LPCSTR)MAKEINTRESOURCE(cmd-1);
模拟window桌面实现ci.nShow
=SW_SHOWNORMAL;
模拟window桌面实现
模拟window桌面实现pContextMenu
->InvokeCommand(&ci);
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现pContextMenu
->Release();
模拟window桌面实现g_pIContext2
=NULL;
模拟window桌面实现g_pIContext3
=NULL;
模拟window桌面实现::DestroyMenu(hMenu);
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现
staticLRESULTCALLBACKHookWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam)
模拟window桌面实现模拟window桌面实现
...{
模拟window桌面实现模拟window桌面实现
switch(message)...{
模拟window桌面实现
caseWM_MENUCHAR://onlysupportedbyIContextMenu3
模拟window桌面实现模拟window桌面实现
if(g_pIContext3)...{
模拟window桌面实现LRESULTlResult
=0;
模拟window桌面实现g_pIContext3
->HandleMenuMsg2(message,wParam,lParam,&lResult);
模拟window桌面实现
return(lResult);
模拟window桌面实现}

模拟window桌面实现
break;
模拟window桌面实现
caseWM_DRAWITEM:
模拟window桌面实现
caseWM_MEASUREITEM:
模拟window桌面实现模拟window桌面实现
if(wParam)...{
模拟window桌面实现
break;//ifwParam!=0thenthemessageisnotmenu-related
模拟window桌面实现
}

模拟window桌面实现
模拟window桌面实现
caseWM_INITMENUPOPUP:
模拟window桌面实现模拟window桌面实现
if(g_pIContext2)...{
模拟window桌面实现g_pIContext2
->HandleMenuMsg(message,wParam,lParam);
模拟window桌面实现}

模拟window桌面实现模拟window桌面实现
else...{
模拟window桌面实现g_pIContext3
->HandleMenuMsg(message,wParam,lParam);
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现
return(message==WM_INITMENUPOPUP?0:TRUE);
模拟window桌面实现
break;
模拟window桌面实现
default:
模拟window桌面实现
break;
模拟window桌面实现}

模拟window桌面实现
模拟window桌面实现
return::CallWindowProc((WNDPROC)GetProp(hWnd,TEXT("oldWndProc")),hWnd,message,wParam,lParam);
模拟window桌面实现}

相关文章:

  • 2022-12-23
  • 2021-12-10
  • 2021-12-10
  • 2022-12-23
  • 2022-12-23
  • 2021-12-22
  • 2021-11-04
  • 2022-12-23
猜你喜欢
  • 2022-01-17
  • 2022-12-23
  • 2021-08-06
  • 2021-10-06
  • 2021-04-28
  • 2021-12-20
  • 2022-12-23
相关资源
相似解决方案