CMyWnd.cpp
上传用户:hyb6888
上传日期:2016-01-24
资源大小:5186k
文件大小:11k
源码类别:

输入法编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "stdio.h"
  3. #include "CMyWnd.h"
  4. #include "windows.h"
  5. #include "math.h" 
  6. #include "myHDC.h" 
  7. #include "myWinAttrib.h"
  8. //一个类实例只能有一个窗口
  9. //如果一个实例调用了多次,只有第一次调用时会建立窗口,后面的只显示窗口
  10. WNDPROC CMyWnd::CreateThunk()
  11. {
  12.     Thunk*  thunk = new Thunk;
  13.     
  14.     ///////////////////////////////////////////////
  15.     //系统调用m_thunk时的堆栈:
  16.     //ret HWND MSG WPARAM LPARAM
  17.     //-------------------------------------------
  18.     //栈顶                                             栈底
  19.     ///////////////////////////////////////////////
  20.     //call Offset
  21.     //调用code[0],call执行时会把下一条指令压栈,即把Proc压栈
  22.     thunk->Call = 0xE8;        // call [rel]32
  23.     thunk->Offset = (size_t)&(((Thunk*)0)->Code)-(size_t)&(((Thunk*)0)->Proc);  // 偏移量,跳过Proc到Code[0]
  24.     thunk->Proc = CMyWnd::stdProc;  //静态窗口过程
  25.     //pop ecx,Proc已压栈,弹出Proc到ecx 
  26.     thunk->Code[0] = 0x59;  //pop ecx
  27.     
  28.     //mov dword ptr [esp+0x4],this
  29.     //Proc已弹出,栈顶是返回地址,紧接着就是HWND了。
  30.     //[esp+0x4]就是HWND
  31.     thunk->Code[1] = 0xC7;  // mov
  32.     thunk->Code[2] = 0x44;  // dword ptr
  33.     thunk->Code[3] = 0x24;  // disp8[esp]
  34.     thunk->Code[4] = 0x04;  // +4
  35.     thunk->Window = this;
  36.     
  37.     //偷梁换柱成功!跳转到Proc
  38.     //jmp [ecx]
  39.     thunk->Jmp = 0xFF;     // jmp [r/m]32
  40.     thunk->ECX = 0x21;     // [ecx]
  41.     
  42.     m_thunk = (WNDPROC)thunk;
  43.     return m_thunk;
  44. LRESULT WINAPI CMyWnd::stdProc(HWND hWnd,UINT uMsg,UINT wParam,LONG lParam)
  45. {
  46.     CMyWnd* w = (CMyWnd*)hWnd;
  47.     
  48.     return w->WindowProc(uMsg,wParam,lParam);
  49. //①得到This指针,可以直接使用内部的变量,
  50. //②或者是直接调用窗口处理函数。
  51. //③或者使用thunk技术。
  52. //注:在static函中,所有实例都使用同一个函数的,及静态数据。
  53. //由于static为公共代码,无法为每个实例保存一个THIS指针。
  54. //最好还是使用thunk技术
  55. LRESULT WINAPI CMyWnd::InitProc(HWND hWnd,UINT uMsg,UINT wParam,LONG lParam)
  56. {   
  57.     if(uMsg == WM_NCCREATE)
  58.     {
  59. CMyWnd *w = NULL;
  60. w = (CMyWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams;
  61. if(w)
  62. {
  63. //记录hWnd
  64. w->m_hWnd = hWnd;
  65.     
  66. //改变窗口过程为m_thunk
  67. w->Oldproc=*(WNDPROC)SetWindowLong(hWnd,GWL_WNDPROC,(LONG)w->CreateThunk());
  68. return (*(WNDPROC)(w->GetThunk()))(hWnd,uMsg,wParam,lParam);   
  69. }
  70.     } 
  71.     return DefWindowProc(hWnd,uMsg,wParam,lParam);
  72. }
  73. ///////////////////////////////////////////////////////////
  74. CMyWnd::~CMyWnd()
  75. {
  76. strcpy(showtxt,"");
  77. DestroyWindow(m_hWnd);
  78. m_hWnd=NULL;
  79. }
  80. CMyWnd::CMyWnd()
  81. {
  82. strcpy(showtxt,"Hello world");
  83. m_hWnd=NULL;
  84. zoom=1;
  85. chrHeight=100;
  86. chrWidth=50;
  87.     BackfileName[0]=0;
  88.     PictfileName[0]=0;
  89. WhiteBack[0]=0;
  90. }
  91. CMyWnd::SetBackPict(char *BackName,char *PictName,char *WhiteName)
  92. {
  93.  strcpy(BackfileName,BackName);
  94.  strcpy(PictfileName,PictName);
  95.  strcpy(WhiteBack,WhiteName);
  96. }
  97. CMyWnd::SetText(char *ss)
  98. {
  99. strcpy(showtxt,ss);
  100. }
  101. BOOL CMyWnd::Create(LPCTSTR szClassName, LPCTSTR szTitle, HINSTANCE hInstance, HWND hWndParent , DWORD dwStyle ,DWORD dwExStyle, HMENU hMenu )
  102. {
  103.   myWinAttrib setwin;
  104.   WNDCLASS wnd;
  105. wnd.cbClsExtra = NULL;
  106. wnd.cbWndExtra = NULL;
  107. wnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  108. wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
  109. wnd.hIcon = LoadIcon(NULL, 0);
  110. wnd.hInstance = hInstance;
  111. wnd.lpfnWndProc = InitProc;
  112. wnd.lpszClassName = szClassName;
  113. wnd.lpszMenuName = NULL;
  114. wnd.style= CS_OWNDC|CS_DBLCLKS;
  115. if(hWndParent!=0)
  116. {
  117. dwStyle |= WS_CHILDWINDOW;
  118. dwStyle = 0x56010000;
  119. }
  120. else
  121. wnd.style= CS_OWNDC|CS_DBLCLKS;
  122. if (!RegisterClass(&wnd))
  123. {
  124. //MessageBox(NULL, "Can not register window class", "Error", MB_OK | MB_ICONINFORMATION);
  125. //return -1;
  126. }
  127. if(m_hWnd==NULL)
  128. m_hWnd=::CreateWindowEx(dwExStyle, szClassName, szTitle, dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWndParent, hMenu, hInstance, this);
  129. //SetParent(m_hWnd,hWndParent);
  130. ShowWindow(m_hWnd,1);
  131. UpdateWindow(m_hWnd);
  132. myHwndParent=hWndParent;
  133. setwin.mySetWindow(m_hWnd, RGB(255,255,255), 0,1);
  134. return m_hWnd != NULL;
  135. }
  136.  LRESULT WINAPI CMyWnd::WindowProc(UINT uMsg,UINT wParam,LONG lParam)
  137.  {
  138.   HDC hDC;
  139.   static BOOL  fCanMove = FALSE;
  140.   static BOOL  PicCanMove = FALSE;
  141.   static POINT ptdif;
  142.   static POINT backptdif;
  143.          POINT pt;
  144.   static SIZE  sz;
  145.   static RECT  drc;
  146.          RECT  Parentdrc;
  147.   static long x,y;
  148.   static long  add=1 ;
  149.   static  double a ;
  150.   
  151.   static  int dipcolor=200 ;
  152.   myWinAttrib setwin;
  153.   PAINTSTRUCT ps;
  154.   switch (uMsg)
  155.   {
  156.     case WM_CREATE:
  157. setwin.mySetWindow(m_hWnd, RGB(255,255,255), 0,1);
  158. strcpy(Showss,"");
  159. dm.StartHDC(GetDC(m_hWnd),100,80);
  160.     Backhdc.StartHDC(GetDC(m_hWnd),3000,3000);
  161. if(myHwndParent!=NULL)
  162. {
  163. GetWindowRect(myHwndParent,&drc);
  164. ParentHeight=drc.bottom-drc.top;
  165. ParentWidth=drc.right-drc.left;
  166. }
  167. else
  168. {
  169. ParentHeight=0;
  170. ParentWidth=0;
  171. }
  172. r=sqrt(chrWidth*chrWidth+chrHeight*chrHeight);
  173.     if(dm.loadPic(PictfileName)==NULL)
  174. MessageBox(0,dm.Picname,0,0);
  175.     if(Backhdc.loadPic(BackfileName)==NULL)
  176. MessageBox(0,Backhdc.Picname,0,0);
  177. Backhdc.LoadPicWidth;
  178.     SetTimer (m_hWnd,1,100,0);
  179. //SetWindowPos(m_hWnd,0,0,0,2*r,2*r,SWP_NOMOVE);
  180.       break;
  181.     case WM_PAINT:
  182.       hDC = BeginPaint(m_hWnd, &ps);
  183.   //TextOut(hDC,x,y, showtxt,strlen(showtxt));
  184.   //BitBlt(GetDC(m_hWnd),0,0,200,200,Backhdc.hdc,0,0,SRCCOPY);
  185.      BitBlt(GetDC(m_hWnd),0,0,Backhdc.LoadPicWidth,Backhdc.LoadPicHeight,Backhdc.hdc,0,0,SRCCOPY);
  186.       EndPaint(m_hWnd, &ps);
  187.       break;
  188.     case WM_TIMER:
  189. a=a+add;
  190. OutTextPic(Showss,0,0,GetDC(m_hWnd),dm.hdc,chrWidth, chrHeight,a,Backhdc.hdc);
  191.       SetWindowPos(m_hWnd,0,0,0,((strlen(Showss)-1)*chrWidth*2+2*r)*zoom,2*r*zoom,SWP_NOMOVE);
  192. break;
  193.    case WM_MOUSEMOVE:
  194. if(fCanMove==TRUE)
  195. {
  196. GetCursorPos( &pt );
  197. MoveWindow(m_hWnd,pt.x - ptdif.x, pt.y - ptdif.y, sz.cx,sz.cy,TRUE);
  198. //使用SetWindowPos作移动时会改变集焦。可用MoveWindow解决。
  199. //在不移动时可以使用它。
  200. }
  201. if(PicCanMove==TRUE)
  202. {
  203. GetCursorPos( &pt );
  204. BitBlt(Backhdc.hdc,0,0,Backhdc.LoadPicWidth, Backhdc.LoadPicHeight,0,0,0,WHITENESS);
  205. BitBlt(Backhdc.hdc,pt.x - ptdif.x+backptdif.x, pt.y - ptdif.y+backptdif.y,Backhdc.LoadPicWidth, Backhdc.LoadPicHeight,Backhdc.outhdc,0,0,SRCCOPY);
  206.         RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE|RDW_ERASENOW);//RDW_ERASE
  207. }
  208.  y=lParam/0x10000;
  209.  x=lParam%0x10000;
  210.    break;
  211.    case WM_KEYDOWN:
  212. Showss[0]=wParam;Showss[1]=0;
  213.     RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE);//RDW_ERASE
  214.     if(wParam==27)
  215. {
  216. if(myHwndParent==NULL)
  217. PostQuitMessage(0);
  218. else
  219. DestroyWindow(m_hWnd);
  220. KillTimer(m_hWnd,1);
  221. }
  222. break;
  223.     case WM_LBUTTONDOWN:
  224. SetCapture(m_hWnd);
  225. GetCursorPos( &pt );
  226. GetWindowRect(m_hWnd,&drc);
  227. ptdif.x = pt.x - drc.left;
  228. ptdif.y = pt.y - drc.top;
  229. if(myHwndParent!=0)
  230. {
  231. GetWindowRect(myHwndParent,&Parentdrc);
  232. ptdif.x +=Parentdrc.left;
  233. ptdif.y +=Parentdrc.top;
  234. }
  235. sz.cx = drc.right - drc.left;
  236. sz.cy = drc.bottom - drc.top;
  237. fCanMove=TRUE;
  238. break;
  239.     case WM_LBUTTONUP:
  240. ReleaseCapture();
  241. fCanMove=FALSE;
  242. break;
  243.     case WM_RBUTTONDOWN:
  244. SetCapture(m_hWnd);
  245. PicCanMove=TRUE;
  246. GetCursorPos( &pt );
  247. ptdif.x = pt.x;
  248. ptdif.y = pt.y ;
  249. PicCanMove=TRUE;
  250. break;
  251.     case WM_RBUTTONUP:
  252. GetCursorPos( &pt );
  253. backptdif.x+=pt.x - ptdif.x;
  254. backptdif.y+=pt.y - ptdif.y;
  255. ReleaseCapture();
  256. PicCanMove=FALSE;
  257.     RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE|RDW_ERASENOW|RDW_ERASE);//RDW_ERASE
  258. break;
  259.     case WM_LBUTTONDBLCLK:
  260. setwin.mySetWindow(m_hWnd, RGB(255,255,255), 0,1);
  261. if (add==2)
  262. add=-2;
  263. else
  264. add=2;
  265.     RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE);//RDW_ERASE
  266. break;
  267.     case WM_RBUTTONDBLCLK:
  268. dipcolor+=10;
  269. if(dipcolor>255)
  270. dipcolor=50;
  271. setwin.mySetWindow(m_hWnd, RGB(255,255,255), dipcolor,2);
  272. break;
  273.     case WM_DESTROY:
  274. if(myHwndParent==NULL)
  275. PostQuitMessage(0);
  276. else
  277. DestroyWindow(m_hWnd);
  278. KillTimer(m_hWnd,1);
  279. break;
  280. default: 
  281. return DefWindowProc(m_hWnd, uMsg, wParam, lParam);
  282.   }
  283.   return 0;
  284. }
  285. CMyWnd::StopTime()
  286. {
  287. KillTimer(m_hWnd,1);
  288. }
  289. CMyWnd::ContinueTime()
  290. {
  291. SetTimer (m_hWnd,1,100,0);
  292. }
  293. CMyWnd::OutTextPic(char *ss,long x,long y,HDC hDC1,HDC hDC2, long dw , long dh,double a,HDC backhdc)
  294. {
  295. int i,index;
  296. myHDC tt,temtt,pp;
  297. char temss[100];
  298. long r,outdw;
  299. strcpy(temss,ss);
  300. r=sqrt(dw*dw+dh*dh);
  301. outdw=dw*2*strlen(temss)+r*2;
  302.     tt.StartHDC(hDC1,outdw,500);
  303.     temtt.StartHDC(hDC1,outdw,500);
  304.     pp.StartHDC(hDC1,outdw,500);
  305. strupr(temss);
  306. tt.loadPic(WhiteBack);//装入一个白色背景
  307. for(i=0;i<strlen(temss);i++)
  308. {
  309. index=temss[i]-65;
  310. OutPicture(r,r,tt.hdc,dw*2*index,0,hDC2,dw,dh,a);
  311. TransparentBlt2(temtt.hdc,dw*2*i,0,dw*2+r,r*2,tt.hdc,0,0,dw*2+r,r*2,RGB(255,255,255));
  312. //BitBlt(temtt.hdc,dw*2*i,0,dw*2+r,r*2,tt.hdc,0,0,SRCAND);//
  313. }
  314. BitBlt(pp.hdc,0,0,outdw,r*2,backhdc,x,y,SRCCOPY);
  315. TransparentBlt2(pp.hdc,0,0,outdw*zoom,r*2*zoom,temtt.hdc,0,0,outdw,r*2,RGB(255,255,255));
  316. BitBlt(hDC1,x,y,outdw*zoom,r*2,pp.hdc,0,0,SRCCOPY);
  317. }
  318. CMyWnd::OutPicture(long x,long y,HDC hDC1,long startx,long starty,HDC hDC2, long dw , long dh,double a)
  319. {
  320.   POINT pt[3];
  321.   double sidas,sidac ;
  322. sidac =cos(a * 0.0174533);
  323. sidas =sin(a * 0.0174533);
  324. pt[0].y = -dh * sidac -dw * sidas + y;
  325. pt[0].x =  dh * sidas -dw * sidac + x;
  326. pt[1].y = -dh * sidac +dw * sidas + y;
  327. pt[1].x =  dh * sidas +dw * sidac + x;
  328. pt[2].y =  dh * sidac -dw * sidas + y;
  329. pt[2].x = -dh * sidas -dw * sidac + x;
  330. BitBlt(hDC1,0,0,2000,500,0,0,0,WHITENESS);//WHITENESS此白色并不是RGB(255,255,255)
  331. PlgBlt(hDC1,pt,hDC2,startx,starty, dw*2,dh*2,0,0,0);
  332. }
  333. void CMyWnd::TransparentBlt2(HDC hdc0,
  334. int nX0,int nY0,int nW0,int nH0,
  335. HDC hdc1,
  336. int nX1,int nY1,int nW1,int nH1,
  337. UINT Tcol)
  338.  
  339. {
  340. HBITMAP hBMP   =CreateCompatibleBitmap(hdc0,nW0, nH0);
  341. // HBITMAP mBMP   =CreateCompatibleBitmap(hdc0,nW0, nH0);
  342. HBITMAP mBMP   =CreateBitmap(nW0,nH0,1,1,NULL); //建单色位图
  343. HDC hDC    =CreateCompatibleDC(hdc0);
  344. HDC mDC    =CreateCompatibleDC(hdc0);
  345. HBITMAP oldBMP =(HBITMAP)SelectObject(hDC, hBMP);
  346. HBITMAP oldmBMP=(HBITMAP)SelectObject(mDC, mBMP);
  347. //拷备位图到hDC中
  348. if (nW0==nW1&&nH0==nH1)
  349. BitBlt(hDC,0,0,nW0,nH0,hdc1,nX1,nY1,SRCCOPY);
  350. else
  351. StretchBlt(hDC,0,0,nW0,nH0,hdc1,nX1,nY1,nW1,nH1,SRCCOPY);
  352. SetBkColor(hDC, Tcol);//除去背景色的其他色形成轮括
  353. BitBlt(mDC,0,0,nW0,nH0,hDC,0,0,SRCCOPY);    
  354. //在单色的mDC设备中形成位图的黑色轮括。
  355. SetBkColor(hDC, RGB(0,0,0));            //设置形成图形与后的0值色
  356. SetTextColor(hDC, RGB(255,255,255));    //设置需要处理颜色的范围
  357. BitBlt(hDC,0,0,nW0,nH0,mDC,0,0,SRCAND); //取出实际以黑色为背景的图形。
  358. SetBkColor(hdc0,RGB(255,255,255));
  359. SetTextColor(hdc0,RGB(0,0,0));
  360. //在背景图上形成轮括
  361. BitBlt(hdc0,nX0,nY0,nW0,nH0,mDC,0,0,SRCAND); // SRCAND   dest=source AND dest
  362. BitBlt(hdc0,nX0,nY0,nW0,nH0,hDC,0,0,SRCPAINT);//SRCPAINT dest=source OR  dest  
  363. SelectObject(hDC,oldBMP);
  364. SelectObject(mDC,oldmBMP);
  365. DeleteDC(hDC);
  366. DeleteDC(mDC);
  367. DeleteObject(hBMP);
  368. DeleteObject(mBMP);
  369. }
  370. void CMyWnd::SetShowchar(char *ss)
  371. {
  372. if(ss==0)
  373. Showss[0]=0;
  374. else
  375. if(strlen(ss)>0)
  376. strcpy(Showss,ss);
  377. else
  378. Showss[0]=0;
  379. RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE);//RDW_ERASE
  380. }