#include <windows.h> //windows程序设计必须要包含的头文件 #include <string.h> #include <stdio.h> #include "resource.h" //资源文件 //响应函数// LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; //回调函数的声明,将在wndclass.lpfnWndProc = WndProc;中用到 //全局变量// HINSTANCE _hInstance;//实例句柄 HWND _hwnd; //定义一个窗口句柄,用来标识窗口 TCHAR szAppName[] = TEXT ("WinApi") ; //将"HelloWin"赋给szAppName[] //注册窗口/ void InitApplication(HINSTANCE hInstance) { WNDCLASS wndclass ; //定义一个窗口类,该窗口类也是个结构体,下面的语句是修改结构体数据 wndclass.style = CS_HREDRAW | CS_VREDRAW ; //窗口绘制模式为水平重绘和垂直重绘 wndclass.lpfnWndProc = WndProc ; //回调函数为一开始申明的函数 wndclass.cbClsExtra = 0 ; //类的附加内存(额外的),不需要就设为0 wndclass.cbWndExtra = 0 ; //窗口的附加内存,同上 wndclass.hInstance = hInstance ;// 当前实例为系统传递过来的实例,只能是这样,其它系统帮你做好了 wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; //加载ICON图标,NULL加载系统的图标,第二个参数使系统里面图标的一个标识 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; //同上,不过是加载光标 wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;// 设置窗口背景为白色 wndclass.lpszMenuName = NULL ; //因为没有菜单,所以设为空 wndclass.lpszClassName= szAppName ; //你为你设计的这个窗口类取个名字,在hwnd = CreateWindow中用到 RegisterClass (&wndclass); } //创建窗口并显示/ bool InitInstance(HINSTANCE hInstance,int iCmdShow) { //创建窗口 _hwnd = CreateWindow( szAppName, // window class name 窗口类的名字 TEXT ("Windows API 基础开发框架"), // window caption 窗口的标题 WS_OVERLAPPEDWINDOW|WS_VSCROLL, // window style 窗口的风格 CW_USEDEFAULT,// initial x position 默认的窗口左上角的X、Y点 CW_USEDEFAULT,// initial y position 100,// initial x size 默认窗口显示的宽和高 100,// initial y size NULL, // parent window handle 没有父窗口 NULL, // window menu handle 没有菜单、菜单句柄为空 hInstance, // program instance handle 程序当前实例,由系统传递 NULL) ; // creation parameters if(!_hwnd) { return false; } ShowWindow (_hwnd, iCmdShow) ; //显示窗口 UpdateWindow (_hwnd) ; //更新窗口 _hInstance=hInstance; return true; } //主函数/ //主函数即入口函数 int WINAPI WinMain (HINSTANCE hInstance, //实例句柄 HINSTANCE hPrevInstance,//上一个实例句柄 PSTR szCmdLine, //指向一个0结尾的字符串 int iCmdShow) //窗口开始的大小 { MSG msg ; //定义一个消息结构体,该结构体包含消息的几个数据 InitApplication(hInstance); //注册你刚刚设计好的窗口 InitInstance(hInstance,iCmdShow);//生成主窗口实例 while (GetMessage (&msg, NULL, 0, 0)) //消息循环,获取消息 { TranslateMessage (&msg) ; //翻译消息, DispatchMessage (&msg) ;// 分发消息 } return msg.wParam ; //返回消息里的一个参数,只有退出程序时该值才为0 } /回调函数的定义/ LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static int cxClient,cyClient,cxChar,cyChar,cxCaps,iVscrollPos=0,iVscrollMax; static HDC hdc; static int line,row; static TCHAR buffer[100]; static int lineText=10; static TCHAR text[6][10]= { TEXT("1"),TEXT("2"),TEXT("3"),TEXT("4"),TEXT("5"),TEXT("6") }; static SCROLLINFO si={0}; switch (message) { case WM_CREATE: //窗口刚刚创建好时发送的消息 { hdc=GetDC(hwnd); TEXTMETRIC tm; GetTextMetrics(hdc,&tm); cxChar=tm.tmAveCharWidth; cyChar=tm.tmHeight+tm.tmExternalLeading; cxCaps=(tm.tmPitchAndFamily & 1 ? 3:2)*cxChar/2; ReleaseDC(hwnd,hdc); } return 0; case WM_SIZE: //窗口大小改变 { cxClient=LOWORD(lParam); cyClient=HIWORD(lParam); line=cyClient/cyChar; row=cxClient/cxChar; si.cbSize=sizeof(si); si.fMask=SIF_RANGE|SIF_PAGE; si.nMin=0; si.nMax=5; si.nPage=line; SetScrollInfo(hwnd,SB_VERT,&si,TRUE); } return 0 ; case WM_PAINT: { hdc=GetDC(hwnd); ValidateRect(hwnd,NULL); //设置整个窗口有效,否则WM_PAINT消息仍旧会加入队列中 si.cbSize=sizeof(si); si.fMask=SIF_POS; GetScrollInfo(hwnd,SB_VERT,&si); iVscrollPos=si.nPos; for(int i=0;i<line && iVscrollPos+i<6;++i) { TextOut(hdc,0,i*cyChar,text[iVscrollPos+i],lstrlen(text[iVscrollPos+i])); } ReleaseDC(hwnd,hdc); } return 0; case WM_VSCROLL: { si.cbSize=sizeof(si); si.fMask=SIF_ALL; GetScrollInfo(hwnd,SB_VERT,&si); iVscrollPos=si.nPos; switch(LOWORD(wParam)) { case SB_TOP: si.nPos = si.nMin ; break ; case SB_BOTTOM: si.nPos = si.nMax ; break ; case SB_LINEUP: si.nPos -=1 ; break ; case SB_LINEDOWN: si.nPos += 1 ; break ; case SB_PAGEUP: si.nPos -= si.nPage ; break ; case SB_PAGEDOWN: si.nPos += si.nPage ; break ; case SB_THUMBTRACK: si.nPos = si.nTrackPos ; break ; default: break ; } si.fMask=SIF_POS; SetScrollInfo(hwnd,SB_VERT,&si,TRUE); //pos越界会自动处理 GetScrollInfo(hwnd,SB_VERT,&si); //获取设置后的下标,如果越界则肯定与之前的位置相同 if (si.nPos !=iVscrollPos) //因为有上边的情况可能POS没有改变,所以做判断 { ScrollWindow(hwnd,0,cyChar*(iVscrollPos-si.nPos),NULL,NULL); InvalidateRect (hwnd, NULL, TRUE) ; //令整个窗口无效 UpdateWindow(hwnd); //立即重绘无效窗口 } return 0 ; } return 0; case WM_DESTROY: //窗口销毁时的消息 { PostQuitMessage (0) ; //退出程序 } return 0 ; default: return DefWindowProc (hwnd, message, wParam, lParam) ; } }