首页 > 代码库 > SDK源码分析 2

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