SDK源码分析 6

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDK源码分析 6相关的知识,希望对你有一定的参考价值。

  1 #include <windows.h>
  2 #define DIVISIONS 5
  3 
  4 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  5 LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
  6 TCHAR szChildClass[] = TEXT("Checker3_Child");
  7 int idFocus = 0;//窗口ID
  8 
  9 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPervInstance, PSTR szCmdLine, int iCmdShow)
 10 {
 11     WNDCLASS wndclass;
 12     MSG msg;
 13     HWND hWnd;
 14     TCHAR Name_1[] = TEXT("MyClass"), Name_2[] = TEXT("MyWindows");
 15 
 16     wndclass.cbClsExtra = 0;
 17     wndclass.cbWndExtra = 0;
 18     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 19     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 20     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 21     wndclass.hInstance = hInstance;
 22     wndclass.lpfnWndProc = WndProc;
 23     wndclass.lpszClassName = Name_1;
 24     wndclass.lpszMenuName = NULL;
 25     wndclass.style = CS_HREDRAW | CS_VREDRAW;
 26 
 27     RegisterClass(&wndclass);
 28 
 29     wndclass.lpfnWndProc = ChildWndProc;//同一个类派生的窗口过程
 30     wndclass.cbWndExtra = sizeof(long);//分配额外的 窗口过程空间
 31     wndclass.hIcon = NULL;//图标设置空
 32     wndclass.lpszClassName = szChildClass;//类名设置
 33 
 34     RegisterClass(&wndclass);
 35 
 36     hWnd = CreateWindow(Name_1, Name_2, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
 37         NULL, NULL, hInstance, NULL);
 38     ShowWindow(hWnd, iCmdShow);
 39     UpdateWindow(hWnd);
 40 
 41     while (GetMessage(&msg, NULL, NULL, NULL))
 42     {
 43         TranslateMessage(&msg);
 44         DispatchMessage(&msg);
 45     }
 46     return msg.wParam;
 47 }
 48 
 49 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)//主窗口
 50 {
 51     static HWND hwndChild[DIVISIONS][DIVISIONS], z = 0;//数组 [5][5]=25
 52     int cxBlock, cyBlock, x, y;
 53 
 54     switch (msg)
 55     {
 56     case WM_CREATE://窗口生成
 57         for (x = 0; x < DIVISIONS; x++)
 58         {
 59             for (y = 0; y < DIVISIONS; y++)
 60             {
 61                 //数组窗口句柄保存
 62                 hwndChild[x][y] = CreateWindow(szChildClass, NULL, WS_CHILDWINDOW | WS_VISIBLE,
 63                     0, 0, 0, 0, hWnd, (HMENU)(y<<8|x), (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);
 64                 //窗口风格为 子窗口 并且可视 初始大小位置 全部0 父窗口是主窗口 ,后面的参数为子窗口特有的标记 随意 不同即可 后面的是获取窗口实力句柄
 65             }
 66         }
 67         return 0;
 68     case WM_SIZE:
 69         cxBlock = LOWORD(lParam) / DIVISIONS;
 70         cyBlock = HIWORD(lParam) / DIVISIONS;
 71 
 72         for (x = 0; x < DIVISIONS; x++)
 73         {
 74             for (y = 0; y < DIVISIONS; y++)
 75             {
 76                 MoveWindow(hwndChild[x][y], x*cxBlock, y*cyBlock, cxBlock, cyBlock, TRUE);
 77                 //设置窗口位置以及大小。
 78             }
 79         }
 80         return 0;
 81     case WM_LBUTTONDOWN:
 82         MessageBeep(0);
 83         return 0;
 84     case WM_SETFOCUS://主窗口获得焦点的时候
 85         SetFocus(GetDlgItem(hWnd, idFocus));//设置 子窗口 idFocus ID的窗口 为焦点窗口 默认为0; 步骤:1
 86         return 0;
 87     case WM_KEYDOWN:
 88         x = idFocus & 0xFF;// 按位或 取出x的值
 89         y = idFocus >> 8;//右移 8位 取出y的值
 90         switch (wParam)
 91         {
 92         case VK_UP: y--; break;
 93         case VK_DOWN:y++; break;
 94         case VK_LEFT:x--; break;
 95         case VK_RIGHT:x++; break;
 96         case VK_HOME:x = y = 0; break;
 97         case VK_END:x = y = DIVISIONS - 1; break;
 98         default:return 0;
 99         }
100 
101         x = (x + DIVISIONS) % DIVISIONS;//防止出屏幕
102         y = (y + DIVISIONS) % DIVISIONS;//防止出屏幕
103 
104         idFocus = y << 8 | x;//还原数据
105         SetFocus(GetDlgItem(hWnd, idFocus));//设置 子窗口ID 为焦点
106         //当主窗口接受到键盘消息 就 移动 x和y的值  最后设置 子窗口ID 为焦点 跳转 子窗口获取焦点
107         return 0;
108     case WM_DESTROY:
109         PostQuitMessage(0);
110         return 0;
111     }
112     return DefWindowProc(hWnd, msg, wParam, lParam);
113 }
114 
115 LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)//子窗口过程 25个全部调用这个
116 {
117     HDC hdc;
118     PAINTSTRUCT ps;
119     RECT rect;
120 
121     switch (msg)
122     {
123     case WM_CREATE:
124         SetWindowLong(hWnd, 0, 0);//设置额外 内存为 0
125         return 0;
126     case WM_KEYDOWN://因为当前焦点在子窗口 如果接收不为 空格或回车 就返回主窗口
127         if (wParam != VK_RETURN && wParam != VK_SPACE)
128         {
129             SendMessage(GetParent(hWnd), msg, wParam, lParam);//发送消息 画XX
130             return 0;
131 
132         }
133 
134     case WM_LBUTTONDOWN:
135         SetWindowLong(hWnd, 0, 1 ^ GetWindowLong(hWnd, 0));//设置额外 内存 为 0或1
136         SetFocus(hWnd);
137         InvalidateRect(hWnd, NULL, FALSE);//立即重绘
138         return 0;
139     case WM_SETFOCUS://子窗口获得焦点 步骤:2
140         idFocus = GetWindowLong(hWnd, GWL_ID);//获得子窗口 ID号 给全局变量
141     case WM_KILLFOCUS://失去焦点
142         InvalidateRect(hWnd, NULL, TRUE);//重绘窗口 步骤:3
143         return 0;
144     case WM_PAINT://重绘窗口 步骤:4 下面代码不执行 跳到 步骤:5执行
145         hdc = BeginPaint(hWnd, &ps);
146 
147         GetClientRect(hWnd, &rect);//获取窗口矩形大小
148         Rectangle(hdc, 0, 0, rect.right, rect.bottom);//重新绘制矩形
149         if (GetWindowLong(hWnd, 0))//如果标记了 就画XX
150         {
151             MoveToEx(hdc, 0, 0, NULL);
152             LineTo(hdc, rect.right, rect.bottom);
153             MoveToEx(hdc, 0, rect.bottom, NULL);
154             LineTo(hdc, rect.right, 0);
155         }
156 
157         if (hWnd == GetFocus())// 这里是 步骤:5 画出 虚线矩形
158         {
159             rect.left += rect.right / 10;// 矩形的左边 = 矩形的左边 + 矩形的右边 / 10
160             rect.right -= rect.left;//矩形的右边 = 矩形的右边 - 矩形的左边
161             rect.top += rect.bottom / 10;//矩形的顶边 = 矩形的顶边 + 矩形的底边 / 10
162             rect.bottom -= rect.top;//矩形的底边 = 矩形的底边 - 矩形的顶边
163             
164             //假设 矩形 宽 20 高 20
165             //那么  左边 = 0, 右边 = 20, 顶边 = 0, 底边 = 20
166             // 左边=10  右边=10 顶边=10 底边=10
167             
168             SelectObject(hdc, GetStockObject(NULL_BRUSH));//设置为空画刷
169             SelectObject(hdc, CreatePen(PS_DASH, 0, 0));//设置画笔 为 虚线画笔
170             Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);//画出矩形
171             DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));//删除 选择的画笔
172 
173         }
174 
175         EndPaint(hWnd, &ps);
176         return 0;
177     }
178     return DefWindowProc(hWnd, msg, wParam, lParam);
179 }

 

以上是关于SDK源码分析 6的主要内容,如果未能解决你的问题,请参考以下文章

SDK源码分析 4

SDK源码分析 7

Android 插件化VirtualApp 源码分析 ( 目前的 API 现状 | 安装应用源码分析 | 安装按钮执行的操作 | 返回到 HomeActivity 执行的操作 )(代码片段

SDK源码分析 2

Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段

Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段