PlatformView.cpp
上传用户:easylife05
上传日期:2007-02-14
资源大小:393k
文件大小:15k
源码类别:

PlugIns编程

开发平台:

Visual C++

  1. // PlatformView.cpp : CPlatformView 类的实现
  2. //
  3. #include "stdafx.h"
  4. #include "Platform.h"
  5. #include "mainfrm.h"
  6. #include "PlatformDoc.h"
  7. #include "PlatformView.h"
  8. //----支持COM-----------------------------
  9. #include <objbase.h>
  10. #include <comcat.h>
  11. #include <initguid.h>
  12. #include <assert.h>
  13. #include "LmhPlugin.h" //CATID_LMHPluginCategory
  14. const int CLSID_STRING_SIZE = 39 ;
  15. #include <afxtempl.h>
  16. #include <oleauto.h>
  17. //-----------------------------------------
  18. #include "../plugin2/Plugin2.h"
  19. #include "../plugin2/Plugin2_i.c"
  20. interface IPlugin;
  21. //---------------------------
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #endif
  25. //#include "commstruct.h"
  26. //struct myGraph;
  27. // CPlatformView
  28. IMPLEMENT_DYNCREATE(CPlatformView, CScrollView)
  29. BEGIN_MESSAGE_MAP(CPlatformView, CScrollView)
  30. // 标准打印命令
  31. ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
  32. ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
  33. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
  34. ON_WM_RBUTTONDOWN()
  35. ON_WM_MOUSEMOVE()
  36. ON_WM_LBUTTONDBLCLK()
  37. ON_WM_LBUTTONDOWN()
  38. ON_WM_LBUTTONUP()
  39. END_MESSAGE_MAP()
  40. // CPlatformView 构造/销毁
  41. CPlatformView::CPlatformView()
  42. {
  43. //-----------------------------
  44. m_AddMenu1=false; m_AddMenu2=false;
  45. m_basicMenuID=m_currentMenuID=ID_DYNAMENU;
  46. //初始化菜单--------------------
  47. m_child1Menu.DestroyMenu();
  48. m_child1Menu.CreatePopupMenu();
  49. m_child2Menu.DestroyMenu();
  50. m_child2Menu.CreatePopupMenu();
  51. //------------------------------
  52. m_MenuPluginList.InitMenu(ID_DYNAMENU);
  53. m_pServer=NULL;
  54. m_pDlg=NULL;
  55. }
  56. CPlatformView::~CPlatformView()
  57. {
  58. m_child1Menu.DestroyMenu();
  59. m_child2Menu.DestroyMenu();
  60. m_MenuPluginList.ClearAll();
  61. m_interfaceList.ClearAll();
  62. if (m_pServer!=NULL)
  63. {
  64. ((IServer*)m_pServer)->Release();
  65. //delete m_pServer;
  66. }
  67. m_ActiveXList.ClearAll();
  68. }
  69. BOOL CPlatformView::PreCreateWindow(CREATESTRUCT& cs)
  70. {
  71. // TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
  72. // 样式
  73. return CScrollView::PreCreateWindow(cs);
  74. }
  75. // CPlatformView 绘制
  76. void CPlatformView::OnDraw(CDC* pDC)
  77. {
  78. CPlatformDoc* pDoc = GetDocument();
  79. ASSERT_VALID(pDoc);
  80. POSITION pos=m_interfaceList.m_interfaceList.GetHeadPosition();
  81. CInterfaceItem *mItem;
  82. while(pos!=NULL)
  83. {
  84. mItem=m_interfaceList.m_interfaceList.GetAt(pos);
  85. IPlugin * pPlugin;
  86. pPlugin=(IPlugin*)( mItem->m_interface);
  87. pPlugin->ReDraw();
  88. m_interfaceList.m_interfaceList.GetNext(pos);
  89. }
  90. }
  91. void CPlatformView::OnInitialUpdate()
  92. {
  93. CScrollView::OnInitialUpdate();
  94. CSize sizeTotal;
  95. // TODO: 计算此视图的合计大小
  96. sizeTotal.cx = sizeTotal.cy = 100;
  97. SetScrollSizes(MM_TEXT, sizeTotal);
  98. }
  99. // CPlatformView 打印
  100. BOOL CPlatformView::OnPreparePrinting(CPrintInfo* pInfo)
  101. {
  102. // 默认准备
  103. return DoPreparePrinting(pInfo);
  104. }
  105. void CPlatformView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  106. {
  107. // TODO: 打印前添加额外的初始化
  108. }
  109. void CPlatformView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  110. {
  111. // TODO: 打印后添加清除过程
  112. }
  113. // CPlatformView 诊断
  114. #ifdef _DEBUG
  115. void CPlatformView::AssertValid() const
  116. {
  117. CScrollView::AssertValid();
  118. }
  119. void CPlatformView::Dump(CDumpContext& dc) const
  120. {
  121. CScrollView::Dump(dc);
  122. }
  123. CPlatformDoc* CPlatformView::GetDocument() const // 非调试版本是内联的
  124. {
  125. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPlatformDoc)));
  126. return (CPlatformDoc*)m_pDocument;
  127. }
  128. #endif //_DEBUG
  129. // CPlatformView 消息处理程序
  130. void CPlatformView::OnRButtonDown(UINT nFlags, CPoint point)
  131. {
  132. // TODO: 在此添加消息处理程序代码和/或调用默认值
  133. //DoPopupMenu(IDR_POPUP_TABLE);
  134. CScrollView::OnRButtonDown(nFlags, point);
  135. }
  136. void CPlatformView::DoPopupMenu(UINT nMenuID)
  137. {
  138. //NULL Operation!
  139. }
  140. void CPlatformView::OnPopupCommand(UINT nMenuID)
  141. {
  142. //NULL Operation!
  143. }
  144. //----------------------------------
  145. //刷新插件的菜单项
  146. //---------------------------------
  147. void CPlatformView::RefreshMenu(CMenu &childMenu, char* menuName)
  148. {
  149. //在主菜单上加上完全动态菜单
  150. CMenu* pTopMenu = AfxGetMainWnd()->GetMenu();
  151. int iPos = pTopMenu->GetMenuItemCount()-1;
  152. pTopMenu->InsertMenu(iPos,MF_POPUP|MF_BYPOSITION,(UINT_PTR)childMenu.m_hMenu,menuName);
  153. AfxGetMainWnd()->GetActiveWindow()->DrawMenuBar();
  154. //---------------
  155. }
  156. //-------------------------------------
  157. //
  158. //  在此添加命令处理程序代码
  159. //-------------------------------------
  160. BOOL CPlatformView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  161. {
  162. // If pHandlerInfo is NULL, then handle the message
  163. if (pHandlerInfo == NULL)
  164. {
  165. if (nCode == CN_COMMAND)
  166. {
  167. // Handle WM_COMMAND message
  168. if (nID==ID_MENU_OPTION)
  169. {
  170. if (m_AddMenu1) return TRUE;
  171. BeginWaitCursor(); 
  172. CheckInPlugin(CATID_LMHPluginCategory);
  173. RefreshMenu(m_child1Menu,"插件");
  174. m_AddMenu1=true;
  175. EndWaitCursor(); 
  176. return TRUE;
  177. }
  178. if (nID==ID_ACTIVEXMENU)
  179. {
  180. if (m_AddMenu2) return TRUE;
  181. BeginWaitCursor(); 
  182. CheckInActiveX(CATID_LMHActiveXCategory);
  183. RefreshMenu(m_child2Menu,"控件");
  184. m_AddMenu2=true;
  185. EndWaitCursor(); 
  186. return TRUE;
  187. }
  188. if ((nID>=m_basicMenuID) && (nID<m_currentMenuID))
  189. {
  190. CLSID clsID;
  191. short actionID;
  192. clsID=m_MenuPluginList.Find(nID,actionID);
  193. //--------------------------------------------
  194. if (actionID==-1) //调用控件功能
  195. CallActiveX(clsID);
  196. else //调用插件功能
  197. CallPlugin(clsID,actionID);
  198. //--------------------------------------------
  199. return TRUE;
  200. }
  201. }
  202. else if (nCode == CN_UPDATE_COMMAND_UI)
  203. {
  204. // 激活加载菜单项
  205. if (nID==ID_MENU_OPTION)
  206. {
  207. ((CCmdUI*)pExtra)->Enable(TRUE);
  208. return TRUE;
  209. }
  210. if (nID==ID_ACTIVEXMENU)
  211. {
  212. ((CCmdUI*)pExtra)->Enable(TRUE);
  213. return TRUE;
  214. }
  215. //---激活PLUGIN菜单项------------------------
  216. if ((nID>=m_basicMenuID) && (nID<m_currentMenuID))
  217. {
  218. ((CCmdUI*)pExtra)->Enable(TRUE);
  219. return TRUE;
  220. }
  221. //----------------------------------------------
  222. }
  223. }
  224. return CScrollView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  225. }
  226. //////////////////////////////////////////////////
  227. //函数:
  228. //功能:Convert a CLSID to a char string.
  229. // 
  230. ///////////////////////////////////////////////////
  231. void CLSIDtochar(   const CLSID& clsid,
  232. char* szCLSID,
  233. int length)
  234. {
  235. assert(length >= CLSID_STRING_SIZE) ;
  236. // Get CLSID
  237. LPOLESTR wszCLSID = NULL ;
  238. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  239. assert(SUCCEEDED(hr)) ;
  240. // Convert from wide characters to non-wide characters.
  241. wcstombs(szCLSID, wszCLSID, length);
  242. // Free memory.
  243. CoTaskMemFree(wszCLSID) ;
  244. }
  245. ///////////////////////////////////////////////////////////
  246. //函数:
  247. //功能:获得COM类的名
  248. //时间:
  249. //------------------------
  250. BOOL getFriendlyName(const CLSID& clsid, LPCTSTR szFriendlyName, int iLength)
  251. {
  252. HKEY hKey;
  253. char szKeyBuf[1024] ;
  254. char szCLSID[CLSID_STRING_SIZE] ;
  255. // Convert the clsid to a string.
  256. CLSIDtochar(clsid, szCLSID, CLSID_STRING_SIZE) ;
  257. // Make the key.
  258. sprintf(szKeyBuf, "CLSID\%s", szCLSID) ;
  259. // Create and open key and subkey.
  260. long lResult = RegOpenKeyEx(    HKEY_CLASSES_ROOT ,
  261. szKeyBuf,
  262. 0,
  263. KEY_ALL_ACCESS,
  264. &hKey) ;
  265. if (lResult != ERROR_SUCCESS)
  266. {
  267. return FALSE ;
  268. }
  269. // Set the Value.
  270. ASSERT(szFriendlyName != NULL) ;
  271. DWORD dwSize = iLength ;
  272. lResult = RegQueryValueEx( hKey, NULL, NULL, NULL, (BYTE *)szFriendlyName, &dwSize);
  273. RegCloseKey(hKey);
  274. return lResult == ERROR_SUCCESS;
  275. }
  276. //---------------------------------------
  277. //函数:CheckInPlugin(GUID catID)
  278. //功能:用于注册Compotent Category
  279. //输入:Compotent Category的GUID
  280. //输出:成功为TRUE,失败为FALSE
  281. //时间:2003/6/17 PM3:10
  282. //作者:
  283. //---------------------------------------
  284. BOOL CPlatformView::CheckInPlugin(GUID catID)
  285. {
  286. // Create the standard COM Category Manager
  287. ICatInformation* pICatInformation = NULL ;
  288. HRESULT hr = ::CoCreateInstance(    CLSID_StdComponentCategoriesMgr,
  289. NULL, CLSCTX_ALL, IID_ICatInformation,
  290. (void**)&pICatInformation) ;
  291. if (FAILED(hr))
  292. {
  293. ASSERT(hr) ;
  294. return FALSE;
  295. }
  296. // Array of Categories
  297. int cIDs = 1 ;
  298. CATID IDs[1] ;
  299. IDs[0] = catID; //组件目录的GUID
  300. // Get the IEnumCLSID interface.
  301. IEnumCLSID* pIEnumCLSID = NULL ;
  302. hr = pICatInformation->EnumClassesOfCategories(cIDs, IDs, 0, NULL, &pIEnumCLSID) ;
  303. ASSERT(SUCCEEDED(hr)) ;
  304. // Get the next CLSID in the list.
  305. //char szFriendlyName[128] ;
  306. CLSID clsid ;
  307. IPlugin * pPlugin;
  308. BOOL firstPlugin=true;
  309. while ((hr = pIEnumCLSID->Next(1, &clsid, NULL)) == S_OK)
  310. {
  311. //---------创建查询到的COM------------------------
  312. hr = ::CoCreateInstance(clsid, //COM类的ID
  313. NULL,
  314. CLSCTX_INPROC_SERVER,
  315. IID_IPlugin, //统一接口定义
  316. reinterpret_cast<void**>(&pPlugin)) ; //接口指针
  317. if (FAILED(hr))
  318. {
  319. AfxMessageBox("Failed to create the component.") ;
  320. return FALSE ;
  321. }
  322. int i;
  323. short nCount;
  324. char funName[80];
  325. pPlugin->GetFunctionCount(&nCount);
  326. //-------------------------
  327. HBITMAP hBitmap;
  328. pPlugin->GetToolBarBitmap(&hBitmap);
  329. char pluginName[80];
  330. pPlugin->GetPluginName(pluginName);
  331. ((CMainFrame*)AfxGetMainWnd())->AddPluginToolbar(hBitmap,m_currentMenuID,nCount,pluginName);
  332. //--------------------------
  333. //规定动作序号从0开始
  334. for (i=0;i<nCount;i++) 
  335. {
  336. m_MenuPluginList.Add(clsid,i);
  337. pPlugin->GetFunctionName(i,funName);
  338. if ((!firstPlugin) && (i==0))
  339. RefreshChildMenu(m_child1Menu,true,funName);
  340. else
  341. RefreshChildMenu(m_child1Menu,false,funName);
  342. }
  343. pPlugin->Release();
  344. firstPlugin=false;
  345. }
  346. pICatInformation->Release() ;
  347. m_pServer= new CComObject<CServer>;
  348. _ASSERT(m_pServer != NULL);
  349. CPlatformDoc* pDoc = GetDocument();
  350. m_pServer->m_pDoc=pDoc;
  351. m_pServer->m_pView=this;
  352. ((IServer*)m_pServer)->AddRef();
  353. return TRUE;
  354. }
  355. //-------------------------------------
  356. //函数:RefreshChildMenu(BOOL seprator,char* menuName)
  357. //功能:用于生成菜单的子项
  358. //输入:seprator为是否为分隔符, menuName为菜单的名字
  359. //输出:无
  360. //时间:2003/6/18 PM4:00
  361. //作者:
  362. //-------------------------------------
  363. void CPlatformView::RefreshChildMenu(CMenu &childMenu,BOOL seprator,char* menuName)
  364. {
  365. //为主菜单生动完全动态的子菜单项,每项与一COM方法相关联
  366. //时间:2003/6/18 PM3:00
  367. //if (m_AddMenu) return;
  368. if (seprator)
  369. {
  370. childMenu.AppendMenu(MF_SEPARATOR);
  371. }
  372. childMenu.AppendMenu(MF_STRING,m_currentMenuID, menuName);
  373. m_currentMenuID++;
  374. }
  375. //---------------------------------------
  376. //函数:CallPlugin(CLSID classID, short actionID)
  377. //功能:用于调用插件的功能
  378. //输入:classID为COM的类ID ,actionID为功能的序号
  379. //输出:成功为TRUE,失败为FALSE
  380. //时间:2003/6/18 PM4:00
  381. //作者:
  382. //---------------------------------------
  383. BOOL CPlatformView::CallPlugin(CLSID classID, short actionID)
  384. {
  385. HRESULT hr ;
  386. IPlugin * pPlugin;
  387. pPlugin=(IPlugin*)m_interfaceList.Find(classID);
  388. if (pPlugin==NULL)
  389. {
  390. //创建查询到的COM
  391. hr = ::CoCreateInstance(classID, //COM类的ID
  392. NULL,
  393. CLSCTX_INPROC_SERVER,
  394. IID_IPlugin,//统一接口定义
  395. reinterpret_cast<void**>(&pPlugin)) ; //接口指针
  396. if (FAILED(hr))
  397. {
  398. AfxMessageBox("Failed to create the component.") ;
  399. return FALSE ;
  400. }
  401. m_interfaceList.Add(classID,pPlugin);
  402. }
  403. CDC* cDC=GetDC( );
  404. pPlugin->PassHDC(cDC->m_hDC);
  405. CWnd* cWND=AfxGetMainWnd();
  406. pPlugin->PassHWND(cWND->m_hWnd);
  407. pPlugin->SetServer(((IUnknown*)m_pServer));
  408. pPlugin->DoFunction(actionID);
  409. //pPlugin->Release();
  410. return TRUE;
  411. }
  412. void CPlatformView::OnMouseMove(UINT nFlags, CPoint point)
  413. {
  414. // TODO: 在此添加消息处理程序代码和/或调用默认值
  415. SendMouseMessage(WM_MOUSEMOVE,nFlags,point.x,point.y);
  416. CScrollView::OnMouseMove(nFlags, point);
  417. }
  418. //---------------------------------------------------------
  419. //此函数用于消息传递,向各需要的插件传递鼠标消息
  420. //---------------------------------------------------------
  421. void CPlatformView::SendMouseMessage(UINT Message, UINT flags, int x, int y)
  422. {
  423. POSITION pos=m_interfaceList.m_interfaceList.GetHeadPosition();
  424. CInterfaceItem *mItem;
  425. while(pos!=NULL)
  426. {
  427. mItem=m_interfaceList.m_interfaceList.GetAt(pos);
  428. IPlugin * pPlugin;
  429. pPlugin=(IPlugin*)( mItem->m_interface);
  430. pPlugin->SendMouseMessage(Message,flags,x,y);
  431. m_interfaceList.m_interfaceList.GetNext(pos);
  432. }
  433. }
  434. void CPlatformView::OnLButtonDblClk(UINT nFlags, CPoint point)
  435. {
  436. // TODO: 在此添加消息处理程序代码和/或调用默认值
  437. SendMouseMessage(WM_LBUTTONDBLCLK,nFlags,point.x,point.y);
  438. CScrollView::OnLButtonDblClk(nFlags, point);
  439. }
  440. void CPlatformView::OnLButtonDown(UINT nFlags, CPoint point)
  441. {
  442. // TODO: 在此添加消息处理程序代码和/或调用默认值
  443. SendMouseMessage(WM_LBUTTONDOWN,nFlags,point.x,point.y);
  444. CScrollView::OnLButtonDown(nFlags, point);
  445. }
  446. void CPlatformView::OnLButtonUp(UINT nFlags, CPoint point)
  447. {
  448. // TODO: 在此添加消息处理程序代码和/或调用默认值
  449. SendMouseMessage(WM_LBUTTONUP,nFlags,point.x,point.y);
  450. CScrollView::OnLButtonUp(nFlags, point);
  451. }
  452. //---------------------------------------
  453. //函数:CheckInActiveX(GUID catID)
  454. //功能:用于注册Compotent Category,专用于ActiveX组件
  455. //输入:Compotent Category的GUID
  456. //输出:成功为TRUE,失败为FALSE
  457. //时间:2003/6/30 AM11:20
  458. //作者:
  459. //---------------------------------------
  460. BOOL CPlatformView::CheckInActiveX(GUID catID)
  461. {
  462. // Create the standard COM Category Manager
  463. ICatInformation* pICatInformation = NULL ;
  464. HRESULT hr = ::CoCreateInstance(    CLSID_StdComponentCategoriesMgr,
  465. NULL, CLSCTX_ALL, IID_ICatInformation,
  466. (void**)&pICatInformation) ;
  467. if (FAILED(hr))
  468. {
  469. ASSERT(hr) ;
  470. return FALSE;
  471. }
  472. // Array of Categories
  473. int cIDs = 1 ;
  474. CATID IDs[1] ;
  475. IDs[0] = catID; //组件目录的GUID
  476. // Get the IEnumCLSID interface.
  477. IEnumCLSID* pIEnumCLSID = NULL ;
  478. hr = pICatInformation->EnumClassesOfCategories(cIDs, IDs, 0, NULL, &pIEnumCLSID) ;
  479. ASSERT(SUCCEEDED(hr)) ;
  480. char szFriendlyName[128] ;
  481. CLSID clsid ;
  482. while ((hr = pIEnumCLSID->Next(1, &clsid, NULL)) == S_OK)
  483. {
  484. m_MenuPluginList.Add(clsid,-1);
  485. getFriendlyName(clsid, szFriendlyName, sizeof(szFriendlyName));
  486. RefreshChildMenu(m_child2Menu,false,szFriendlyName);
  487. }
  488. pICatInformation->Release() ;
  489. return TRUE;
  490. }
  491. //---------------------------------------
  492. //函数:CallActiveX(CLSID classID)
  493. //功能:用于调用控件的功能
  494. //输入:classID为ActiveX的类ID
  495. //输出:成功为TRUE,失败为FALSE
  496. //时间:2003/6/30 PM3:10
  497. //作者:
  498. //---------------------------------------
  499. BOOL CPlatformView::CallActiveX(CLSID classID)
  500. {
  501. //HRESULT hr ;
  502. COcxCallDlg * pOcxDlg;
  503. pOcxDlg=m_ActiveXList.Find(classID);
  504. if (pOcxDlg==NULL)
  505. {
  506. //创建查询到的ActiveX调用对话框
  507. pOcxDlg=new COcxCallDlg(classID);
  508. //pOcxDlg->m_classID=classID;
  509. pOcxDlg->Create(IDD_OCXCALLDLG);
  510.         m_ActiveXList.Add(classID,pOcxDlg);
  511. }
  512. pOcxDlg->ShowWindow(SW_SHOWNORMAL);
  513. //pPlugin->Release();
  514. return TRUE;
  515. }