HideWindow.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. #include "StdAfx.h"
  2. #include "HideWindow.h"
  3. #define INTERVAL 20 //触发粘附时鼠标与屏幕边界的最小间隔,单位为象素
  4. #define INFALTE 20 //触发收缩时鼠标与窗口边界的最小间隔,单位为象素
  5. //计时器
  6. #define IDI_CHECKMOUSE 5000 //鼠标离开窗口
  7. #define IDI_BEGINHIDE 5001 //窗口移动标识
  8. #define CM_ELAPSE 300 //鼠标离开窗口
  9. #define BH_ELAPSE 20 //窗口移动时间
  10. #define STEPS_COUNT 7 //总共步数
  11. CHideWindow::CHideWindow(void)
  12. {
  13. m_bSized = false;
  14. m_bTimed = false;
  15. m_bFinished = true;
  16. m_bHiding = false;
  17. m_nWindowHeight = WND_MINSIZE_Y;
  18. m_nTaskBarHeight = 30;
  19. m_nEdgeHeight = 0;
  20. m_nEdgeWidth =0;
  21. m_enHideType = en_None;
  22. m_hOwnHwnd = NULL;
  23. }
  24. CHideWindow::~CHideWindow(void)
  25. {
  26. }
  27. void CHideWindow::HideWindow()
  28. {
  29. if( m_hOwnHwnd == NULL ) return;
  30. if(m_enHideType == en_None) return;
  31. CRect rcWindow;
  32. ::GetWindowRect(m_hOwnHwnd,rcWindow);
  33. INT nHeight = rcWindow.Height();
  34. INT nWidth = rcWindow.Width();
  35. //步幅
  36. INT nStride = 0;
  37. switch(m_enHideType)
  38. {
  39. case en_Top:
  40. {
  41. nStride = nHeight/STEPS_COUNT;
  42. rcWindow.bottom -= nStride;
  43. if(rcWindow.bottom <= m_nEdgeWidth)
  44. {
  45. rcWindow.bottom = m_nEdgeWidth;
  46. m_bFinished = true;
  47. }
  48. rcWindow.top = rcWindow.bottom - nHeight;
  49. }
  50. break;
  51. case en_Bottom:
  52. {
  53. nStride = nHeight/STEPS_COUNT;
  54. rcWindow.top += nStride;
  55. if(rcWindow.top >= (GetSystemMetrics(SM_CYSCREEN) - m_nEdgeWidth))
  56. {
  57. rcWindow.top = GetSystemMetrics(SM_CYSCREEN) - m_nEdgeWidth;
  58. m_bFinished = true;
  59. }
  60. rcWindow.bottom = rcWindow.top + nHeight;
  61. }
  62. break;
  63. case en_Left:
  64. {
  65. nStride = nWidth/STEPS_COUNT;
  66. rcWindow.right -= nStride;
  67. if(rcWindow.right <= m_nEdgeWidth)
  68. {
  69. rcWindow.right = m_nEdgeWidth;
  70. m_bFinished = true;
  71. }
  72. rcWindow.left = rcWindow.right - nWidth;
  73. rcWindow.top = -m_nEdgeHeight;
  74. rcWindow.bottom = GetSystemMetrics(SM_CYSCREEN) - m_nTaskBarHeight;
  75. }
  76. break;
  77. case en_Right:
  78. {
  79. nStride = nWidth/STEPS_COUNT;
  80. rcWindow.left += nStride;
  81. if(rcWindow.left >= (GetSystemMetrics(SM_CXSCREEN) - m_nEdgeWidth))
  82. {
  83. rcWindow.left = GetSystemMetrics(SM_CXSCREEN) - m_nEdgeWidth;
  84. m_bFinished = true;
  85. }
  86. rcWindow.right = rcWindow.left + nWidth;
  87. rcWindow.top = -m_nEdgeHeight;
  88. rcWindow.bottom = GetSystemMetrics(SM_CYSCREEN) - m_nTaskBarHeight;
  89. }
  90. break;
  91. }
  92. SetWindowPos(HWND_TOPMOST,rcWindow);
  93. }
  94. void CHideWindow::ShowWindow()
  95. {
  96. if( m_hOwnHwnd == NULL ) return;
  97. if(m_enHideType == en_None) return;
  98. CRect rcWindow;
  99. ::GetWindowRect(m_hOwnHwnd,rcWindow);
  100. INT nHeight = rcWindow.Height();
  101. INT nWidth = rcWindow.Width();
  102. INT nStride = 0;
  103. switch(m_enHideType)
  104. {
  105. case en_Top:
  106. {
  107. nStride = nHeight/STEPS_COUNT;
  108. rcWindow.top += nStride;
  109. if(rcWindow.top >= -m_nEdgeHeight)
  110. {
  111. rcWindow.top = -m_nEdgeHeight;
  112. m_bFinished = true;
  113. }
  114. rcWindow.bottom = rcWindow.top + nHeight;
  115. }
  116. break;
  117. case en_Bottom:
  118. {
  119. nStride = nHeight/STEPS_COUNT;
  120. rcWindow.top -= nStride;
  121. if(rcWindow.top <= (GetSystemMetrics(SM_CYSCREEN) - nHeight))
  122. {
  123. rcWindow.top = GetSystemMetrics(SM_CYSCREEN) - nHeight;
  124. m_bFinished = true;
  125. }
  126. rcWindow.bottom = rcWindow.top + nHeight;
  127. }
  128. break;
  129. case en_Left:
  130. {
  131. nStride = nWidth/STEPS_COUNT;
  132. rcWindow.right += nStride;
  133. if(rcWindow.right >= nWidth)
  134. {
  135. rcWindow.right = nWidth;
  136. m_bFinished = true;
  137. }
  138. rcWindow.left = rcWindow.right - nWidth;
  139. rcWindow.top = -m_nEdgeHeight;
  140. rcWindow.bottom = GetSystemMetrics(SM_CYSCREEN) - m_nTaskBarHeight;
  141. }
  142. break;
  143. case en_Right:
  144. {
  145. nStride = nWidth/STEPS_COUNT;
  146. rcWindow.left -= nStride;
  147. if(rcWindow.left <= (GetSystemMetrics(SM_CXSCREEN) - nWidth))
  148. {
  149. rcWindow.left = GetSystemMetrics(SM_CXSCREEN) - nWidth;
  150. m_bFinished = true;
  151. }
  152. rcWindow.right = rcWindow.left + nWidth;
  153. rcWindow.top = -m_nEdgeHeight;
  154. rcWindow.bottom = GetSystemMetrics(SM_CYSCREEN) - m_nTaskBarHeight;
  155. }
  156. break;
  157. }
  158. SetWindowPos(HWND_TOPMOST,rcWindow);
  159. }
  160. BOOL CHideWindow::SetWindowPos(HWND hWndInsertAfter, LPCRECT pCRect, UINT nFlags)
  161. {
  162. return ::SetWindowPos(m_hOwnHwnd,hWndInsertAfter,pCRect->left, pCRect->top,
  163. (pCRect->right - pCRect->left), (pCRect->bottom - pCRect->top), nFlags);
  164. }
  165. void CHideWindow::FixMoving(UINT fwSide, LPRECT pRect)
  166. {
  167. CPoint point;
  168. ::GetCursorPos(&point);
  169. INT nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
  170. INT nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
  171. INT nHeight = pRect->bottom - pRect->top;
  172. INT nWidth = pRect->right - pRect->left;
  173. //粘附在上边
  174. if (point.y <= INTERVAL)
  175. {
  176. pRect->bottom = nHeight - m_nEdgeHeight;
  177. pRect->top = -m_nEdgeHeight;
  178. m_enHideType = en_Top;
  179. }
  180. //粘附在下边
  181. else if(point.y >= (nScreenHeight - INTERVAL - m_nTaskBarHeight))
  182. {
  183. pRect->top = nScreenHeight - m_nTaskBarHeight - nHeight;
  184. pRect->bottom = nScreenHeight - m_nTaskBarHeight;
  185. m_enHideType = en_Bottom;
  186. }
  187. //粘附在左边
  188. else if (point.x < INTERVAL)
  189. {
  190. if(!m_bSized)
  191. {
  192. CRect tRect;
  193. ::GetWindowRect(m_hOwnHwnd,tRect);
  194. m_nWindowHeight = tRect.Height();
  195. }
  196. pRect->right = nWidth;
  197. pRect->left = 0;
  198. pRect->top = -m_nEdgeHeight;
  199. pRect->bottom = nScreenHeight - m_nTaskBarHeight;
  200. m_bSized = TRUE;
  201. m_enHideType = en_Left;
  202. }
  203. //粘附在右边
  204. else if(point.x >= (nScreenWidth - INTERVAL))
  205. {
  206. if(!m_bSized)
  207. {
  208. CRect tRect;
  209. ::GetWindowRect(m_hOwnHwnd,tRect);
  210. m_nWindowHeight = tRect.Height();
  211. }
  212. pRect->left = nScreenWidth - nWidth;
  213. pRect->right = nScreenWidth;
  214. pRect->top = -m_nEdgeHeight;
  215. pRect->bottom = nScreenHeight - m_nTaskBarHeight;
  216. m_bSized = true;
  217. m_enHideType = en_Right;
  218. }
  219. //不粘附
  220. else
  221. {
  222. if(m_bSized)
  223. {
  224. pRect->bottom = pRect->top + m_nWindowHeight;
  225. m_bSized = false;
  226. InvalidateRect(m_hOwnHwnd,NULL,FALSE);
  227. SetWindowPos(HWND_TOPMOST,CRect(pRect->left,pRect->top,pRect->right,m_nWindowHeight));
  228. }
  229. //如果Timer开启了,则关闭之
  230. if(m_bTimed)
  231. {
  232. if(::KillTimer(m_hOwnHwnd,IDI_CHECKMOUSE) == 1)
  233. m_bTimed = false;
  234. }
  235. m_enHideType = en_None;
  236. }
  237. }
  238. void CHideWindow::FixSizing(UINT fwSide, LPRECT pRect)
  239. {
  240. if( m_bFinished ) return;
  241. CRect rcClient(pRect);
  242. if(rcClient.Width() < WND_MINSIZE_X || rcClient.Height() < WND_MINSIZE_Y)
  243. {
  244. switch(fwSide)
  245. {
  246. case WMSZ_BOTTOM:
  247. {
  248. pRect->bottom = pRect->top + WND_MINSIZE_Y;
  249. }
  250. break;
  251. case WMSZ_BOTTOMLEFT:
  252. {
  253. if(rcClient.Width() <= WND_MINSIZE_X)
  254. pRect->left = pRect->right - WND_MINSIZE_X;
  255. if(rcClient.Height() <= WND_MINSIZE_Y)
  256. pRect->bottom = pRect->top + WND_MINSIZE_Y;
  257. }
  258. break;
  259. case WMSZ_BOTTOMRIGHT:
  260. {
  261. if(rcClient.Width() < WND_MINSIZE_X)
  262. pRect->right = pRect->left + WND_MINSIZE_X;
  263. if(rcClient.Height() < WND_MINSIZE_Y)
  264. pRect->bottom = pRect->top + WND_MINSIZE_Y;
  265. }
  266. break;
  267. case WMSZ_LEFT:
  268. {
  269. pRect->left = pRect->right - WND_MINSIZE_X;
  270. }
  271. break;
  272. case WMSZ_RIGHT:
  273. {
  274. pRect->right = pRect->left + WND_MINSIZE_X;
  275. }
  276. break;
  277. case WMSZ_TOP:
  278. {
  279. pRect->top = pRect->bottom - WND_MINSIZE_Y;
  280. }
  281. break;
  282. case WMSZ_TOPLEFT:
  283. {
  284. if(rcClient.Width() <= WND_MINSIZE_X)
  285. pRect->left = pRect->right - WND_MINSIZE_X;
  286. if(rcClient.Height() <= WND_MINSIZE_Y)
  287. pRect->top = pRect->bottom - WND_MINSIZE_Y;
  288. }
  289. break;
  290. case WMSZ_TOPRIGHT:
  291. {
  292. if(rcClient.Width() < WND_MINSIZE_X)
  293. pRect->right = pRect->left + WND_MINSIZE_X;
  294. if(rcClient.Height() < WND_MINSIZE_Y)
  295. pRect->top = pRect->bottom - WND_MINSIZE_Y;
  296. }
  297. break;
  298. }
  299. }
  300. }
  301. void CHideWindow::HideLoop( UINT nIDEvent )
  302. {
  303. if(nIDEvent == IDI_CHECKMOUSE )
  304. {
  305. CPoint point;
  306. GetCursorPos(&point);
  307. CRect rcWindow;
  308. ::GetWindowRect(m_hOwnHwnd,rcWindow);
  309. rcWindow.InflateRect(INFALTE,INFALTE);
  310. if(!rcWindow.PtInRect(point))
  311. {
  312. ::KillTimer(m_hOwnHwnd,IDI_CHECKMOUSE);
  313. m_bTimed = false;
  314. m_bFinished = false;
  315. m_bHiding = true;
  316. ::SetTimer(m_hOwnHwnd,IDI_BEGINHIDE,BH_ELAPSE,NULL);
  317. }
  318. ::InvalidateRect(m_hOwnHwnd,NULL,FALSE);
  319. }
  320. else if(nIDEvent == IDI_BEGINHIDE)
  321. {
  322. if(m_bFinished)
  323. ::KillTimer(m_hOwnHwnd,IDI_BEGINHIDE);
  324. else
  325. m_bHiding ? HideWindow() : ShowWindow();
  326. ::InvalidateRect(m_hOwnHwnd,NULL,FALSE);
  327. }
  328. }
  329. void CHideWindow::BeginHide(CPoint point)
  330. {
  331. if( (m_enHideType != en_None) && !m_bTimed && (point.x < GetSystemMetrics(SM_CXSCREEN) + INFALTE))
  332. {
  333. ::SetTimer(m_hOwnHwnd,IDI_CHECKMOUSE,CM_ELAPSE,NULL);
  334. m_bTimed = true;
  335. m_bFinished = false;
  336. m_bHiding = false;
  337. ::SetTimer(m_hOwnHwnd,IDI_BEGINHIDE,BH_ELAPSE,NULL); //开启显示过程
  338. }
  339. }
  340. void CHideWindow::SetHideWindow( HWND hWnd,int nEdgeHeight/*=3*/,int nEdgeWidth/*=3*/ )
  341. {
  342. m_hOwnHwnd = hWnd;
  343. //获得边缘高度和宽度
  344. m_nEdgeHeight = nEdgeHeight;
  345. m_nEdgeWidth = nEdgeWidth;
  346. }