没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|其它|编辑:郝浩|2006-03-08 11:40:00.000|阅读 1716 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
BOOL WINAPI IsShadowEnabled() { BOOL bEnabled = FALSE; if (SystemParametersInfo(SPI_GETDROPSHADOW, 0, bEnabled,0)) { return bEnabled; } return FALSE; }其中 SPI_GETDROPSHADOW 在VC6里面没有被声明,你需要自已声明它:
HBITMAP WINAPI GetScreenBitmap (LPCRECT pRect) { HDC hDC; HDC hMemDC; HBITMAP hNewBitmap = NULL; if ((hDC = ::GetDC(NULL)) != NULL ) { if ((hMemDC = ::CreateCompatibleDC(hDC)) != NULL) { if ((hNewBitmap = ::CreateCompatibleBitmap(hDC, pRect->right - pRect->left, pRect->bottom - pRect->top)) != NULL) { HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDC, hNewBitmap); ::BitBlt(hMemDC, 0, 0, pRect->right - pRect->left, pRect->bottom - pRect->top, hDC, pRect->left, pRect->top, SRCCOPY); ::SelectObject(hMemDC, (HGDIOBJ)hOldBitmap); } ::DeleteDC(hMemDC); } ::ReleaseDC(NULL, hDC); } return hNewBitmap; }下面这两个函数要做的事就差不多了:
void CMenuWndHook::OnNcPaint() { CWindowDC dc(CWnd::FromHandle(m_hWnd)); OnPrint(&dc); } void CMenuWndHook::OnPrint(CDC *pDC) { CRect rc; GetWindowRect(m_hWnd, &rc); rc.OffsetRect(-rc.TopLeft()); // 绘制阴影 if (!IsShadowEnabled()) { CDC cMemDC; cMemDC.CreateCompatibleDC (pDC); HGDIOBJ hOldBitmap = ::SelectObject (cMemDC.m_hDC, m_bmpBack); pDC->BitBlt (0, rc.bottom - 4, rc.Width() - 4, 4, &cMemDC, 0, rc.bottom - 4, SRCCOPY); pDC->BitBlt (rc.right - 4, 0, 4, rc.Height(), &cMemDC, rc.right - 4, 0, SRCCOPY); DrawShadow(pDC, rc); rc.right -= 4; rc.bottom -= 4; } // 绘制边框 pDC->Draw3dRect(rc, m_crFrame[0], m_crFrame[1]); rc.DeflateRect (1, 1); pDC->Draw3dRect(rc, m_crFrame[2], m_crFrame[3]); }在指定的矩形区域内绘制阴影的全局函数(当然这些函数不一定都要做成全局函数,我把它们写成了全局函数是因为在好几个类中都用到了它们, 写成全局函数便于调用) 也许你会觉得这不符合面向对象编程的思想,其实面向过程的编程思想,并不一定就比面向对象的思想落后,我把这些比较独立的函数写成全局函数,当作API函数用,还是觉得很方便的,如果硬要将它们塞到一个类里面,反而觉得很郁闷 。:-).
void DrawShadow(CDC *pDC, CRect rect); void DrawShadow(CDC *pDC, CRect rect) { COLORREF oldcolor = RGB(255, 255, 255); BYTE newValR, newValG, newValB; BYTE AlphaArray[] = {140, 170, 212, 240}; BYTE AlphaArray2[] = {170, 205, 220, 240, 240, 250, 255}; // 底部的阴影 ----------------------------------------- int i, j; for (j = 0; j < 4; j++) { for (i = 6; i <= rect.right - 5; i++) { oldcolor = pDC->GetPixel(i, rect.bottom - (4 - j)); newValR = GetRValue(oldcolor) * AlphaArray[j] / 255; newValG = GetGValue(oldcolor) * AlphaArray[j] / 255; newValB = GetBValue(oldcolor) * AlphaArray[j] / 255; pDC->SetPixel(i, rect.bottom - (4 - j), RGB(newValR, newValG, newValB)); } } // 右边的阴影 ----------------------------------------- for (i = 0; i < 4; i++) { for (j = 6; j <= rect.bottom - 5; j++) { oldcolor = pDC->GetPixel(rect.right - (4 - i), j); newValR = GetRValue(oldcolor) * AlphaArray[i] / 255; newValG = GetGValue(oldcolor) * AlphaArray[i] / 255; newValB = GetBValue(oldcolor) * AlphaArray[i] / 255; pDC->SetPixel(rect.right - (4 - i), j, RGB(newValR, newValG, newValB)); } } // 角上的阴影 -------------------------------------- for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if ((i + j) > 6) break; oldcolor = pDC->GetPixel(rect.right - 4 + i, rect.bottom - 4 + j); newValR = GetRValue(oldcolor) * AlphaArray2[i + j] / 255; newValG = GetGValue(oldcolor) * AlphaArray2[i + j] / 255; newValB = GetBValue(oldcolor) * AlphaArray2[i + j] / 255; pDC->SetPixel(rect.right - 4 + i, rect.bottom - 4 + j, RGB(newValR, newValG, newValB)); oldcolor = pDC->GetPixel(rect.right - 4 + i, rect.top + 5 - j); newValR = GetRValue(oldcolor) * AlphaArray2[i + j] / 255; newValG = GetGValue(oldcolor) * AlphaArray2[i + j] / 255; newValB = GetBValue(oldcolor) * AlphaArray2[i + j] / 255; pDC->SetPixel(rect.right - 4 + i, rect.top + 5 - j, RGB(newValR, newValG, newValB)); oldcolor = pDC->GetPixel(rect.left - i + 5, rect.bottom - 4 + j); newValR = GetRValue(oldcolor) * AlphaArray2[i + j] / 255; newValG = GetGValue(oldcolor) * AlphaArray2[i + j] / 255; newValB = GetBValue(oldcolor) * AlphaArray2[i + j] / 255; pDC->SetPixel(rect.left - i + 5, rect.bottom - 4 + j, RGB(newValR, newValG, newValB)); } } }这么复杂? 唉! 还不是想让它把阴影画得更好看一点, 速度?...在我机子上还过得去。毕竟菜单是不会被频繁地重画的. 这样实现阴影确实有点笨拙,且在意外的时候可能会出现一些不愉快的绘图上的bug. 但是要实现Windows XP 那样完美的菜单阴影还是很难的。我希望已经知道的高手,能指点指点! 谢了先。
void CMenuWndHook::OnNcDestroy() { delete this; // 自杀! } void CMenuWndHook::OnShowWindow(BOOL bShow) { if (!bShow) { delete this; // 自杀2! } }... ..., 好狠哦! 嘿嘿!
CMenuWndHook::~CMenuWndHook() { WNDPROC oldWndProc = (WNDPROC)::GetProp(m_hWnd, CoolMenu_oldProc); if (oldWndProc != NULL) { ::SetWindowLong(m_hWnd, GWL_WNDPROC,(DWORD)(ULONG)oldWndProc); ::RemoveProp(m_hWnd, CoolMenu_oldProc); } m_WndMenuMap.RemoveKey(m_hWnd); if (m_bmpBack.m_hObject != NULL) { m_bmpBack.DeleteObject(); } }这个类基本上写完了,如果我还有什么没讲清的地方,你就再去看看我的源代码吧。我们可以在APP类里面调用它:
............ #include "MenuWndHook.h" ........... BOOL CNewmenuApp::InitInstance() { ....... CMenuWndHook::InstallHook(); } int CNewmenuApp::ExitInstance() { CMenuWndHook::UnInstallHook(); return CWinApp::ExitInstance(); }使用这个类,再加上一个自绘菜单类,你一定可以做出一个非常的精美的菜单来。看看我做的最后成品的截图:
我时常听见人说 Delhpi 程序界面比VC程序的界面如何如何好? 如果是说默认的那些控件的外观,VC确实不如Delphi,(微软也真小气,自已产品的界面做得那么"华丽"(像Office XP/2003,
Windows XP,VS.NET...), 而给我们用的这些控件的外观却这么"老土")...总之真正的精美的有个性的界面是大家自已做出来的,这正是我钟爱VC的理由之一。呵呵。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号