SDK源码分析 2
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDK源码分析 2相关的知识,希望对你有一定的参考价值。
1 #include <windows.h> 2 3 //此处宏定义了一个函数。计算里面的东西 我也不是很懂在计算什么。 4 //观看到第90行 知道这句宏定义的意义 5 //意思是 容量+当前列*一行最大容量+当前位置 6 //例如有 100个 格子。 当前在 第5列 第3个位置 每行10个 有10列 7 //100+5*10+3=153 那么最大是100 为什么有153? 其实很简单。 8 #define BUFFER( x , y ) * (pBuffer + y * cxBuffer + x ) 9 10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//窗口过程 11 12 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR iCmdLine, int iCmdShow) 13 { 14 WNDCLASS wndclass; 15 TCHAR Name_1[] = TEXT("MyClass"), Name_2[] = TEXT("MyWindows"); 16 MSG msg; 17 HWND hWnd; 18 //窗口类设定值 19 wndclass.cbClsExtra = 0; 20 wndclass.cbWndExtra = 0; 21 wndclass.hbrBackground =(HBRUSH) GetStockObject(WHITE_BRUSH); 22 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 23 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 24 wndclass.hInstance = hInstance; 25 wndclass.lpfnWndProc = WndProc; 26 wndclass.lpszClassName = Name_1; 27 wndclass.lpszMenuName = NULL; 28 wndclass.style = CS_HREDRAW | CS_VREDRAW; 29 30 //注册窗口类 和制作窗口 CreateWindow 31 RegisterClass(&wndclass); 32 hWnd=CreateWindow(Name_1, Name_2, WS_OVERLAPPEDWINDOW, 33 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 34 NULL, NULL, hInstance, NULL); 35 36 UpdateWindow(hWnd);//更新显示窗口 37 ShowWindow(hWnd, iCmdShow);//显示窗口 38 39 //消息循环开始 40 while (GetMessage(&msg, NULL, NULL, NULL)) 41 { 42 TranslateMessage(&msg);//翻译键盘消息 43 DispatchMessage(&msg);//转发消息给WndProc 44 } 45 return msg.wParam; 46 } 47 48 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 49 { 50 static DWORD dwCharSet = DEFAULT_CHARSET;//等宽字体 51 static int cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer, xCaret, yCaret; 52 static TCHAR *pBuffer = NULL;//变量字符缓冲区 53 HDC hdc; 54 int x, y, i; 55 PAINTSTRUCT ps; 56 TEXTMETRIC tm; 57 58 switch (msg) 59 { 60 case WM_INPUTLANGCHANGE: 61 dwCharSet = wParam;//获得字体 62 case WM_CREATE: 63 hdc = GetDC(hWnd); 64 SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));//改变字体为等宽 65 66 GetTextMetrics(hdc, &tm);//获得文本信息 67 cxChar = tm.tmAveCharWidth;//设置字符宽度 68 cyChar = tm.tmHeight;//设置字符高度 69 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));//删除字体样式 70 ReleaseDC(hWnd, hdc); 71 case WM_SIZE: 72 if (msg == WM_SIZE) 73 { 74 cxClient = LOWORD(lParam);//获得客户区宽度 75 cyClient = HIWORD(lParam);//获取客户区高度 76 } 77 78 cxBuffer = max(1, cxClient / cxChar);//获得客户区一行最大容量字符 79 cyBuffer = max(1, cyClient / cyChar);//获得客户区一列最大容量字符 80 81 if (pBuffer != NULL)//如果 变量有值 82 { 83 free(pBuffer);//清空变量 84 } 85 //计算pBuffer的值等于 一行最大字符 *一列最大字符 *每个TCHAR大小 86 //也就是 pBuffer=一页客户区 容量 87 pBuffer =(TCHAR*) malloc(cxBuffer*cyBuffer * sizeof(TCHAR)); 88 89 //开始循环 90 for (y = 0; y < cyBuffer; y++)//y=0;y=一列最大值;y++ 91 { 92 for (x = 0; x < cxBuffer; x++)//x=0;x=一行最大值;x++ 93 { 94 BUFFER(x, y) = ‘ ‘;//依次 为每一列 每一行 赋值为 ‘ ‘; 空格 95 } 96 } 97 xCaret = 0; 98 yCaret = 0; 99 if (hWnd == GetFocus())//获得当前窗口是否具有焦点 100 { 101 //这里不是 0,0 因为可以变着来 102 SetCaretPos(xCaret*cxChar, yCaret*cyChar);//设置光标位置 为:0*字符宽度,0*字符高度 103 } 104 InvalidateRect(hWnd, NULL, TRUE);//重画窗口 105 return 0; 106 case WM_SETFOCUS://获得焦点的时候 107 CreateCaret(hWnd, NULL, cxChar, cyChar);//制作光标 当前窗口,实心光标,光标的宽度,光标的高度; 108 SetCaretPos(xCaret*cxChar, yCaret*cyChar);//设置光标位置 为:光标x位置*字符宽度,光标y位置*字符高度; 109 ShowCaret(hWnd);//显示窗口 110 return 0; 111 case WM_KILLFOCUS://失去焦点的时候 112 HideCaret(hWnd);//隐藏光标 113 DestroyCaret();//销毁光标 114 return 0; 115 case WM_KEYDOWN://接受到键盘消息 116 switch (wParam) 117 { 118 case VK_HOME: 119 xCaret = 0;//设置位置为0 120 break; 121 case VK_END: 122 xCaret = cxBuffer - 1;//设置 一行最大值-1 最后的位置 123 break; 124 case VK_PRIOR: 125 yCaret = 0;//设置 列为0 最顶 126 break; 127 case VK_NEXT: 128 yCaret = cyBuffer - 1;//设置 最底部 (列最大-1) 129 break; 130 case VK_LEFT: 131 xCaret = max(xCaret - 1, 0);//设置 位置-1 取 最大的值防止 出去 左 132 break; 133 case VK_RIGHT: 134 xCaret = min(xCaret + 1, cxBuffer - 1);//设置 位置+1 取 最大的值防止 出去 右 135 break; 136 case VK_UP: 137 yCaret = max(yCaret - 1, 0);//设置 位置-1 取 最大的值防止 出去 上 138 break; 139 case VK_DOWN: 140 yCaret = min(yCaret + 1, cyBuffer - 1);//设置 位置+1 取 最大的值防止 出去 下 141 break; 142 case VK_DELETE://删除的一个小算法 143 //x=当前行位置 x<最大行值-1 x++ 144 for (x = xCaret; x < cxBuffer - 1; x++) 145 { 146 //把当前位置的后一位 从删除位置开始赋值给当前位置 列不变 147 BUFFER(x, yCaret) = BUFFER(x + 1, yCaret); 148 } 149 BUFFER(cxBuffer - 1, yCaret) = ‘ ‘;//把最后位置的内容-1 150 HideCaret(hWnd);//隐藏光标 151 hdc = GetDC(hWnd); 152 SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));//设置当前为变宽字体 153 154 //输出 当前位置*字符宽度 ,当前列*字符高度 ,按位与 当前位置输出 pBuffer的内容 ,一行容量-当前位置 155 TextOut(hdc, xCaret*cxChar, yCaret*cyChar, &BUFFER(xCaret, yCaret), cxBuffer - xCaret); 156 //这样的意思是呢 157 //是取地址的意思 &而不是按位与的意思 取当前地址的内容 当时 上面 循环是放在pBuffer里面 cxBuffer-xCaret的意思是 158 //后面的空格也是 别忘记 为什么光标可以随意走动。 159 160 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));//删除字体 161 ReleaseDC(hWnd, hdc); 162 ShowCaret(hWnd);//显示光标 163 break; 164 } 165 return 0; 166 case WM_CHAR: 167 for (i = 0; i < (int)LOWORD(lParam); i++)// 这个参数的低位字节保存的是 重复次数 一般没用 168 { 169 switch(wParam) 170 { 171 case ‘\b‘://如果是 退格键 172 if (xCaret > 0)//如果当前位置不是第一个位置 173 { 174 xCaret--;//当前位置 -1 175 SendMessage(hWnd, WM_KEYDOWN, VK_DELETE, 1);//发送VK_DELETE 删除键 176 } 177 break; 178 case ‘\t‘://tab键 8个空格 179 do 180 { 181 SendMessage(hWnd, WM_CHAR, ‘ ‘, 1);//发送字符消息 182 } while (xCaret % 8 != 0);//判断 执行了几次了 183 break; 184 case ‘\n‘://换行的时候 185 if (++yCaret == cyBuffer) //自增先 如果最大了 跑最上去 186 { 187 yCaret = 0; 188 } 189 break; 190 case ‘\r‘://同上 换行的意思 191 xCaret = 0; 192 if (++yCaret == cyBuffer) 193 { 194 yCaret = 0; 195 } 196 break; 197 case ‘\x1B‘://如果 是ESC 198 //y=0;y< 最大列 y++ 199 for (y = 0; y < cyBuffer; y++) 200 { 201 //x=0;x<行最大 ;x++ 202 for (x = 0; x < cxBuffer; x++) 203 { 204 //当前位置清空 累加 205 BUFFER(x, y) = ‘ ‘; 206 } 207 } 208 xCaret = 0;//清空 209 yCaret = 0;//清空 210 InvalidateRect(hWnd, NULL, FALSE);//重绘窗口 211 break; 212 default: 213 BUFFER(xCaret, yCaret) = (TCHAR)wParam;//一般字符模式下 当前位置 =取得的字符 214 HideCaret(hWnd);//隐藏光标 215 hdc = GetDC(hWnd); 216 SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));//设置变宽字体 217 218 TextOut(hdc, xCaret*cxChar, yCaret*cyChar, &BUFFER(xCaret, yCaret), 1); 219 //输出 位置 : 当前行位置*字符宽度, 当前列位置*字符高度,取地址内容, 每次输出1; 220 221 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));//删除字体 222 ReleaseDC(hWnd, hdc); 223 ShowCaret(hWnd);//显示光标 224 if (++xCaret == cxBuffer)//先自增 行位置 如果等于 最大行容量 225 { 226 xCaret = 0;//行位置为0 227 if (++yCaret == cyBuffer)//先自增 列 如果等于就跑上去 228 { 229 yCaret = 0; 230 } 231 } 232 233 break; 234 } 235 236 } 237 SetCaretPos(xCaret*cxChar, yCaret*cyChar);//显示光标 238 return 0; 239 case WM_PAINT: 240 hdc = BeginPaint(hWnd, &ps); 241 242 SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));//设置为变宽字体 243 //y=0;y<最大列;y++ 244 for (y = 0; y < cyBuffer; y++) 245 { 246 //输出 0,高度为 当前列*字符高度,取需要的位置内容 输出的是 一行内容 247 TextOut(hdc, 0, y*cyChar, &BUFFER(0, y), cxBuffer);//觉得这样可以不要。 因为上面都绘制了。这样怕出错吧 248 } 249 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));//删除字体 250 EndPaint(hWnd, &ps); 251 return 0; 252 case WM_DESTROY: 253 PostQuitMessage(0);//退出程序 254 return 0; 255 } 256 return DefWindowProc(hWnd, msg, wParam, lParam);//很多无用信息给Windows 自己来处理. 257 } 258 //累死我了。。汗颜。。。。
以上是关于SDK源码分析 2的主要内容,如果未能解决你的问题,请参考以下文章
Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段