CMyWnd.cpp
上传用户:hyb6888
上传日期:2016-01-24
资源大小:5186k
文件大小:11k
- #include "stdafx.h"
- #include "stdio.h"
- #include "CMyWnd.h"
- #include "windows.h"
- #include "math.h"
- #include "myHDC.h"
- #include "myWinAttrib.h"
- //一个类实例只能有一个窗口
- //如果一个实例调用了多次,只有第一次调用时会建立窗口,后面的只显示窗口
- WNDPROC CMyWnd::CreateThunk()
- {
- Thunk* thunk = new Thunk;
-
- ///////////////////////////////////////////////
- //系统调用m_thunk时的堆栈:
- //ret HWND MSG WPARAM LPARAM
- //-------------------------------------------
- //栈顶 栈底
- ///////////////////////////////////////////////
- //call Offset
- //调用code[0],call执行时会把下一条指令压栈,即把Proc压栈
- thunk->Call = 0xE8; // call [rel]32
- thunk->Offset = (size_t)&(((Thunk*)0)->Code)-(size_t)&(((Thunk*)0)->Proc); // 偏移量,跳过Proc到Code[0]
- thunk->Proc = CMyWnd::stdProc; //静态窗口过程
- //pop ecx,Proc已压栈,弹出Proc到ecx
- thunk->Code[0] = 0x59; //pop ecx
-
- //mov dword ptr [esp+0x4],this
- //Proc已弹出,栈顶是返回地址,紧接着就是HWND了。
- //[esp+0x4]就是HWND
- thunk->Code[1] = 0xC7; // mov
- thunk->Code[2] = 0x44; // dword ptr
- thunk->Code[3] = 0x24; // disp8[esp]
- thunk->Code[4] = 0x04; // +4
- thunk->Window = this;
-
- //偷梁换柱成功!跳转到Proc
- //jmp [ecx]
- thunk->Jmp = 0xFF; // jmp [r/m]32
- thunk->ECX = 0x21; // [ecx]
-
- m_thunk = (WNDPROC)thunk;
- return m_thunk;
- }
- LRESULT WINAPI CMyWnd::stdProc(HWND hWnd,UINT uMsg,UINT wParam,LONG lParam)
- {
- CMyWnd* w = (CMyWnd*)hWnd;
-
- return w->WindowProc(uMsg,wParam,lParam);
- }
- //①得到This指针,可以直接使用内部的变量,
- //②或者是直接调用窗口处理函数。
- //③或者使用thunk技术。
- //注:在static函中,所有实例都使用同一个函数的,及静态数据。
- //由于static为公共代码,无法为每个实例保存一个THIS指针。
- //最好还是使用thunk技术
- LRESULT WINAPI CMyWnd::InitProc(HWND hWnd,UINT uMsg,UINT wParam,LONG lParam)
- {
- if(uMsg == WM_NCCREATE)
- {
- CMyWnd *w = NULL;
- w = (CMyWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams;
- if(w)
- {
- //记录hWnd
- w->m_hWnd = hWnd;
-
- //改变窗口过程为m_thunk
- w->Oldproc=*(WNDPROC)SetWindowLong(hWnd,GWL_WNDPROC,(LONG)w->CreateThunk());
- return (*(WNDPROC)(w->GetThunk()))(hWnd,uMsg,wParam,lParam);
- }
- }
- return DefWindowProc(hWnd,uMsg,wParam,lParam);
- }
- ///////////////////////////////////////////////////////////
- CMyWnd::~CMyWnd()
- {
- strcpy(showtxt,"");
- DestroyWindow(m_hWnd);
- m_hWnd=NULL;
- }
- CMyWnd::CMyWnd()
- {
- strcpy(showtxt,"Hello world");
- m_hWnd=NULL;
- zoom=1;
- chrHeight=100;
- chrWidth=50;
- BackfileName[0]=0;
- PictfileName[0]=0;
- WhiteBack[0]=0;
- }
- CMyWnd::SetBackPict(char *BackName,char *PictName,char *WhiteName)
- {
- strcpy(BackfileName,BackName);
- strcpy(PictfileName,PictName);
- strcpy(WhiteBack,WhiteName);
- }
- CMyWnd::SetText(char *ss)
- {
- strcpy(showtxt,ss);
- }
- BOOL CMyWnd::Create(LPCTSTR szClassName, LPCTSTR szTitle, HINSTANCE hInstance, HWND hWndParent , DWORD dwStyle ,DWORD dwExStyle, HMENU hMenu )
- {
- myWinAttrib setwin;
- WNDCLASS wnd;
- wnd.cbClsExtra = NULL;
- wnd.cbWndExtra = NULL;
- wnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
- wnd.hIcon = LoadIcon(NULL, 0);
- wnd.hInstance = hInstance;
- wnd.lpfnWndProc = InitProc;
- wnd.lpszClassName = szClassName;
- wnd.lpszMenuName = NULL;
- wnd.style= CS_OWNDC|CS_DBLCLKS;
- if(hWndParent!=0)
- {
- dwStyle |= WS_CHILDWINDOW;
- dwStyle = 0x56010000;
- }
- else
- wnd.style= CS_OWNDC|CS_DBLCLKS;
- if (!RegisterClass(&wnd))
- {
- //MessageBox(NULL, "Can not register window class", "Error", MB_OK | MB_ICONINFORMATION);
- //return -1;
- }
- if(m_hWnd==NULL)
- m_hWnd=::CreateWindowEx(dwExStyle, szClassName, szTitle, dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWndParent, hMenu, hInstance, this);
- //SetParent(m_hWnd,hWndParent);
- ShowWindow(m_hWnd,1);
- UpdateWindow(m_hWnd);
- myHwndParent=hWndParent;
- setwin.mySetWindow(m_hWnd, RGB(255,255,255), 0,1);
- return m_hWnd != NULL;
- }
- LRESULT WINAPI CMyWnd::WindowProc(UINT uMsg,UINT wParam,LONG lParam)
- {
- HDC hDC;
- static BOOL fCanMove = FALSE;
- static BOOL PicCanMove = FALSE;
- static POINT ptdif;
- static POINT backptdif;
- POINT pt;
- static SIZE sz;
- static RECT drc;
- RECT Parentdrc;
- static long x,y;
- static long add=1 ;
- static double a ;
-
- static int dipcolor=200 ;
- myWinAttrib setwin;
- PAINTSTRUCT ps;
- switch (uMsg)
- {
- case WM_CREATE:
- setwin.mySetWindow(m_hWnd, RGB(255,255,255), 0,1);
- strcpy(Showss,"");
- dm.StartHDC(GetDC(m_hWnd),100,80);
- Backhdc.StartHDC(GetDC(m_hWnd),3000,3000);
- if(myHwndParent!=NULL)
- {
- GetWindowRect(myHwndParent,&drc);
- ParentHeight=drc.bottom-drc.top;
- ParentWidth=drc.right-drc.left;
- }
- else
- {
- ParentHeight=0;
- ParentWidth=0;
- }
- r=sqrt(chrWidth*chrWidth+chrHeight*chrHeight);
- if(dm.loadPic(PictfileName)==NULL)
- MessageBox(0,dm.Picname,0,0);
-
- if(Backhdc.loadPic(BackfileName)==NULL)
- MessageBox(0,Backhdc.Picname,0,0);
- Backhdc.LoadPicWidth;
- SetTimer (m_hWnd,1,100,0);
- //SetWindowPos(m_hWnd,0,0,0,2*r,2*r,SWP_NOMOVE);
- break;
- case WM_PAINT:
- hDC = BeginPaint(m_hWnd, &ps);
- //TextOut(hDC,x,y, showtxt,strlen(showtxt));
- //BitBlt(GetDC(m_hWnd),0,0,200,200,Backhdc.hdc,0,0,SRCCOPY);
- BitBlt(GetDC(m_hWnd),0,0,Backhdc.LoadPicWidth,Backhdc.LoadPicHeight,Backhdc.hdc,0,0,SRCCOPY);
- EndPaint(m_hWnd, &ps);
- break;
- case WM_TIMER:
- a=a+add;
- OutTextPic(Showss,0,0,GetDC(m_hWnd),dm.hdc,chrWidth, chrHeight,a,Backhdc.hdc);
- SetWindowPos(m_hWnd,0,0,0,((strlen(Showss)-1)*chrWidth*2+2*r)*zoom,2*r*zoom,SWP_NOMOVE);
- break;
- case WM_MOUSEMOVE:
- if(fCanMove==TRUE)
- {
- GetCursorPos( &pt );
- MoveWindow(m_hWnd,pt.x - ptdif.x, pt.y - ptdif.y, sz.cx,sz.cy,TRUE);
- //使用SetWindowPos作移动时会改变集焦。可用MoveWindow解决。
- //在不移动时可以使用它。
- }
- if(PicCanMove==TRUE)
- {
- GetCursorPos( &pt );
- BitBlt(Backhdc.hdc,0,0,Backhdc.LoadPicWidth, Backhdc.LoadPicHeight,0,0,0,WHITENESS);
- BitBlt(Backhdc.hdc,pt.x - ptdif.x+backptdif.x, pt.y - ptdif.y+backptdif.y,Backhdc.LoadPicWidth, Backhdc.LoadPicHeight,Backhdc.outhdc,0,0,SRCCOPY);
- RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE|RDW_ERASENOW);//RDW_ERASE
- }
- y=lParam/0x10000;
- x=lParam%0x10000;
- break;
- case WM_KEYDOWN:
- Showss[0]=wParam;Showss[1]=0;
- RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE);//RDW_ERASE
- if(wParam==27)
- {
- if(myHwndParent==NULL)
- PostQuitMessage(0);
- else
- DestroyWindow(m_hWnd);
- KillTimer(m_hWnd,1);
- }
- break;
- case WM_LBUTTONDOWN:
- SetCapture(m_hWnd);
- GetCursorPos( &pt );
- GetWindowRect(m_hWnd,&drc);
- ptdif.x = pt.x - drc.left;
- ptdif.y = pt.y - drc.top;
- if(myHwndParent!=0)
- {
- GetWindowRect(myHwndParent,&Parentdrc);
- ptdif.x +=Parentdrc.left;
- ptdif.y +=Parentdrc.top;
- }
- sz.cx = drc.right - drc.left;
- sz.cy = drc.bottom - drc.top;
- fCanMove=TRUE;
- break;
- case WM_LBUTTONUP:
- ReleaseCapture();
- fCanMove=FALSE;
- break;
- case WM_RBUTTONDOWN:
- SetCapture(m_hWnd);
- PicCanMove=TRUE;
- GetCursorPos( &pt );
- ptdif.x = pt.x;
- ptdif.y = pt.y ;
- PicCanMove=TRUE;
- break;
- case WM_RBUTTONUP:
- GetCursorPos( &pt );
- backptdif.x+=pt.x - ptdif.x;
- backptdif.y+=pt.y - ptdif.y;
- ReleaseCapture();
- PicCanMove=FALSE;
- RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE|RDW_ERASENOW|RDW_ERASE);//RDW_ERASE
- break;
- case WM_LBUTTONDBLCLK:
- setwin.mySetWindow(m_hWnd, RGB(255,255,255), 0,1);
- if (add==2)
- add=-2;
- else
- add=2;
- RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE);//RDW_ERASE
- break;
- case WM_RBUTTONDBLCLK:
- dipcolor+=10;
- if(dipcolor>255)
- dipcolor=50;
- setwin.mySetWindow(m_hWnd, RGB(255,255,255), dipcolor,2);
- break;
- case WM_DESTROY:
- if(myHwndParent==NULL)
- PostQuitMessage(0);
- else
- DestroyWindow(m_hWnd);
- KillTimer(m_hWnd,1);
- break;
- default:
- return DefWindowProc(m_hWnd, uMsg, wParam, lParam);
- }
- return 0;
- }
- CMyWnd::StopTime()
- {
- KillTimer(m_hWnd,1);
- }
- CMyWnd::ContinueTime()
- {
- SetTimer (m_hWnd,1,100,0);
- }
- CMyWnd::OutTextPic(char *ss,long x,long y,HDC hDC1,HDC hDC2, long dw , long dh,double a,HDC backhdc)
- {
- int i,index;
- myHDC tt,temtt,pp;
- char temss[100];
- long r,outdw;
- strcpy(temss,ss);
- r=sqrt(dw*dw+dh*dh);
- outdw=dw*2*strlen(temss)+r*2;
- tt.StartHDC(hDC1,outdw,500);
- temtt.StartHDC(hDC1,outdw,500);
- pp.StartHDC(hDC1,outdw,500);
- strupr(temss);
- tt.loadPic(WhiteBack);//装入一个白色背景
- for(i=0;i<strlen(temss);i++)
- {
- index=temss[i]-65;
- OutPicture(r,r,tt.hdc,dw*2*index,0,hDC2,dw,dh,a);
- 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));
- //BitBlt(temtt.hdc,dw*2*i,0,dw*2+r,r*2,tt.hdc,0,0,SRCAND);//
- }
- BitBlt(pp.hdc,0,0,outdw,r*2,backhdc,x,y,SRCCOPY);
- TransparentBlt2(pp.hdc,0,0,outdw*zoom,r*2*zoom,temtt.hdc,0,0,outdw,r*2,RGB(255,255,255));
- BitBlt(hDC1,x,y,outdw*zoom,r*2,pp.hdc,0,0,SRCCOPY);
- }
- CMyWnd::OutPicture(long x,long y,HDC hDC1,long startx,long starty,HDC hDC2, long dw , long dh,double a)
- {
- POINT pt[3];
- double sidas,sidac ;
- sidac =cos(a * 0.0174533);
- sidas =sin(a * 0.0174533);
- pt[0].y = -dh * sidac -dw * sidas + y;
- pt[0].x = dh * sidas -dw * sidac + x;
- pt[1].y = -dh * sidac +dw * sidas + y;
- pt[1].x = dh * sidas +dw * sidac + x;
- pt[2].y = dh * sidac -dw * sidas + y;
- pt[2].x = -dh * sidas -dw * sidac + x;
- BitBlt(hDC1,0,0,2000,500,0,0,0,WHITENESS);//WHITENESS此白色并不是RGB(255,255,255)
- PlgBlt(hDC1,pt,hDC2,startx,starty, dw*2,dh*2,0,0,0);
- }
- void CMyWnd::TransparentBlt2(HDC hdc0,
- int nX0,int nY0,int nW0,int nH0,
- HDC hdc1,
- int nX1,int nY1,int nW1,int nH1,
- UINT Tcol)
-
- {
- HBITMAP hBMP =CreateCompatibleBitmap(hdc0,nW0, nH0);
- // HBITMAP mBMP =CreateCompatibleBitmap(hdc0,nW0, nH0);
- HBITMAP mBMP =CreateBitmap(nW0,nH0,1,1,NULL); //建单色位图
- HDC hDC =CreateCompatibleDC(hdc0);
- HDC mDC =CreateCompatibleDC(hdc0);
- HBITMAP oldBMP =(HBITMAP)SelectObject(hDC, hBMP);
- HBITMAP oldmBMP=(HBITMAP)SelectObject(mDC, mBMP);
- //拷备位图到hDC中
- if (nW0==nW1&&nH0==nH1)
- BitBlt(hDC,0,0,nW0,nH0,hdc1,nX1,nY1,SRCCOPY);
- else
- StretchBlt(hDC,0,0,nW0,nH0,hdc1,nX1,nY1,nW1,nH1,SRCCOPY);
- SetBkColor(hDC, Tcol);//除去背景色的其他色形成轮括
- BitBlt(mDC,0,0,nW0,nH0,hDC,0,0,SRCCOPY);
- //在单色的mDC设备中形成位图的黑色轮括。
- SetBkColor(hDC, RGB(0,0,0)); //设置形成图形与后的0值色
- SetTextColor(hDC, RGB(255,255,255)); //设置需要处理颜色的范围
- BitBlt(hDC,0,0,nW0,nH0,mDC,0,0,SRCAND); //取出实际以黑色为背景的图形。
- SetBkColor(hdc0,RGB(255,255,255));
- SetTextColor(hdc0,RGB(0,0,0));
- //在背景图上形成轮括
- BitBlt(hdc0,nX0,nY0,nW0,nH0,mDC,0,0,SRCAND); // SRCAND dest=source AND dest
- BitBlt(hdc0,nX0,nY0,nW0,nH0,hDC,0,0,SRCPAINT);//SRCPAINT dest=source OR dest
- SelectObject(hDC,oldBMP);
- SelectObject(mDC,oldmBMP);
- DeleteDC(hDC);
- DeleteDC(mDC);
- DeleteObject(hBMP);
- DeleteObject(mBMP);
- }
- void CMyWnd::SetShowchar(char *ss)
- {
- if(ss==0)
- Showss[0]=0;
- else
- if(strlen(ss)>0)
- strcpy(Showss,ss);
- else
- Showss[0]=0;
- RedrawWindow(m_hWnd,0,0,RDW_NOCHILDREN|RDW_INVALIDATE);//RDW_ERASE
- }