zoukankan      html  css  js  c++  java
  • 走进windows编程的世界-----消息处理函数(3)

    二 定时器消息

     1 定时器消息 WM_TIMER
       依照定时器设置时间段,自己主动向窗体发送一个定时器消息WM_TIMER. 优先级比較低.
       定时器精度比較低,毫秒级别.消息产生时间也精度比較低.
       
     2 消息和函数
       2.1 WM_TIMER  - 消息ID
        wParam: 定时器的ID
        lParam: 定时器的处理函数

       2.2 SetTimer  - 设置一个定时器

    UINT SetTimer(
    HWND hWnd, //窗体的句柄,能够为NULL
    UINT nIDEvent,//定时器的ID,0为不预设ID
    UINT uElapse,//定时器时间间隔,毫秒级别
    TIMERPROC lpTimerFunc );//定时器的处理函数,能够为NULL

       返回一个创建好的定时器ID

      2.3 KillTimer - 结束一个定时器

    BOOL KillTimer(
          HWND hWnd,//窗体句柄
          UINT uIDEvent );//定时器ID

      2.4 TimerProc - 定时器处理函数

    VOID CALLBACK TimerProc(
        HWND hwnd, //窗体句柄
        UINT uMsg, //WM_TIMER消息ID
        UINT idEvent,//定时器ID
        DWORD dwTime   );//当前系统时间

      3 使用方式
        3.1 创建定时器 SetTimer
         3.1.1 指定窗体句柄HWND,那么 TIMERPROC 參数能够为空,那么WM_TIMER消息将会发送给指定窗体. 假设未指定, TIMERPROC不能空, 必须指定定时器处理程序.
         3.1.2 假设指定定时器ID,SetTimer会依照这个ID创建定时器, 假设未指定,会返回一个创建定时器ID.

    nTimerID = SetTimer( NULL, 0, 7 * 1000,TimerProc1 );

        3.2 处理消息
          能够依据消息传入定时器ID号,分别处理.
        3.3 结束定时器
          在不使用时, KillTimer结束定时器

    /* File : winpaint.cpp 
     * Auth : sjin 
     * Date : 20140706 
     * Mail : 413977243@qq.com 
     */  
      
    #include <Windows.h>  
    #include <stdio.h>
    
    HINSTANCE g_hInst   = NULL;
    HANDLE    g_hStdOut = NULL;
    UINT      g_nTimerID1 = 0;
    
    
    /*定时器处理函数*/
    void CALLBACK TimerProc1( HWND hWnd,
                              UINT nMsg,
                              UINT idEvent,
                              DWORD dwTime )
    {
        CHAR szText[] = "TimerProc1: Hello Timer
    ";
        WriteConsole( g_hStdOut, szText,
            strlen(szText), NULL, NULL );
    }
    
    void OnCreate( HWND hWnd, UINT nMsg,
        WPARAM wParam, LPARAM lParam )
    {
    	/*
    	UINT SetTimer(
    		HWND hWnd, //窗体的句柄,能够为NULL
    		UINT nIDEvent,//定时器的ID,0为不预设ID
    		UINT uElapse,//定时器时间间隔,毫秒级别
    		TIMERPROC lpTimerFunc );//定时器的处理函数,能够为NULL
    
    		return : 创建好的定时器的ID号
    	*/
        //使用窗体处理函数,创建2个定时器
        SetTimer( hWnd, 1000, 3 * 1000, NULL );    
        SetTimer( hWnd, 1001, 5 * 1000, NULL );
        //使用窗体处理函数, 未指明定时器ID
        g_nTimerID1 = SetTimer( hWnd, 0, 2* 1000, NULL );
        //使用TimerProc处理函数创建定时器
        //SetTimer( hWnd, 1002, 7 * 1000, TimerProc1 );
    	SetTimer( hWnd, 1002, 7 * 1000, NULL );
    }
    
    void OnTimer( HWND hWnd, UINT nMsg,
        WPARAM wParam, LPARAM lParam )
    {
        switch( wParam )
        {
        case 1000:
            {
                CHAR szText[] = "1000: Hello Timer
    ";
                WriteConsole( g_hStdOut, szText,
                    strlen(szText), NULL, NULL );
            }
            break;
        case 1001:
            {
                CHAR szText[] = "1001: Hello Timer
    ";
                WriteConsole( g_hStdOut, szText,
                    strlen(szText), NULL, NULL );
            }
            break;
        case 1002:/*1002 设置对应的处理函数,不会在这里调用*/
            {
                CHAR szText[] = "1002: Hello Timer
    ";
                WriteConsole( g_hStdOut, szText,
                    strlen(szText), NULL, NULL );
            }
            break;
        default:
            {
                CHAR szText[260] = {0};
                sprintf( szText, "%d: Hello Timer
    ",
                    g_nTimerID1 );
                WriteConsole( g_hStdOut, szText,
                    strlen(szText), NULL, NULL );
            }
            break;
        }
    }
    
    LRESULT CALLBACK WndProc( HWND hWnd,
                              UINT nMsg,
                              WPARAM wParam,
                              LPARAM lParam )
    {
        switch( nMsg )
        {
        case WM_CREATE:
            OnCreate( hWnd, nMsg, wParam, lParam );
            break;
        case WM_TIMER:/*处理定时器事件,没有设置定时器回调函数的*/
            OnTimer( hWnd, nMsg, wParam, lParam );
            break;
        case WM_DESTROY:
    		/*销毁定时器
    		BOOL KillTimer(
    			HWND hWnd,//窗体句柄
    			 UINT uIDEvent );//定时器ID
    		*/
            KillTimer( hWnd, 1000 );
    		KillTimer( hWnd, 1001 );
    		KillTimer( hWnd, 1002 );
    		KillTimer( hWnd, g_nTimerID1 );
            PostQuitMessage( 0 );
            return 0;
        }
        return DefWindowProc( hWnd, nMsg,
            wParam, lParam );
    }
    
    BOOL RegisterWnd( LPSTR pszClassName )
    {
        WNDCLASSEX wce = { 0 };
        wce.cbSize        = sizeof( wce );
        wce.cbClsExtra    = 0;
        wce.cbWndExtra    = 0;
        wce.hbrBackground = HBRUSH(COLOR_WINDOW);
        wce.hCursor       = NULL;
        wce.hIcon          = NULL;
        wce.hIconSm       = NULL;
        wce.hInstance     = g_hInst;
        wce.lpfnWndProc   = WndProc;
        wce.lpszClassName = pszClassName;
        wce.lpszMenuName  = NULL;
        wce.style         = CS_VREDRAW|CS_HREDRAW;
    
        ATOM nAtom = RegisterClassEx( &wce );
        if( 0 == nAtom )
        {
            return FALSE;
        }
        return TRUE;
    }
    
    HWND CreateWnd( LPSTR pszClassName )
    {
        HWND hWnd = CreateWindowEx( 0,
            pszClassName, "MyWnd", 
            WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, NULL, NULL, 
            g_hInst, 0 );
        return hWnd;
    }
    
    void DisplayWnd( HWND hWnd )
    {
        ShowWindow( hWnd, SW_SHOW );
        UpdateWindow( hWnd );
    }
    
    void Message( )
    {
        MSG msg = {0};
        while ( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }
    
    void NewConsole()  
    {  
        /*产生控制台*/  
        AllocConsole();  
      
        /*获得控制台标准输出流句柄*/  
        g_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);  
        CHAR szText[] = "Debug Message......:
    ";  
        /*将szText 写到控制台*/  
        WriteConsole(g_hStdOut, szText, strlen(szText), NULL, NULL);  
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
        NewConsole( );
        g_hInst = hInstance;
        RegisterWnd( "MYWND" );
        HWND hWnd = CreateWnd( "MYWND" );
        DisplayWnd( hWnd );
        Message( );
        return 0;
    }

    二 菜单
      1 菜单基础
        菜单 - 每一个菜单会有一个HMENU句柄
        菜单项 - 每一个菜单项会有一个ID号,能够依据这个ID运行不同的操作
      2 菜单的使用
        2.1 菜单创建
          2.1.1 CreateMenu - MENU 菜单
          2.1.2 CreatePopupMenu - POPUPMENU 弹出式菜单
          2.1.3 AppenedMenu - 添加菜单项

    复制代码
      BOOL AppendMenu(
      HMENU hMenu, //菜单句柄
      UINT uFlags, //菜单项标示
      UINT uIDNewItem, //菜单项的ID或者子菜单句柄
      LPCTSTR lpNewItem ); //菜单项的名称
    复制代码

        uFlags: 
          MF_STRING - lpNewItem是一个字符串
          MF_POPUP  - uIDNewItem是一个子菜单句柄
          MF_SEPARATOR - 添加分隔项
          MF_CHECKED/MF_UNCHECKED - 设置和取消菜单项的对勾
          MF_DISABLED/MF_ENABLE - 菜单项禁止和同意状态
       2.2 菜单的命令响应
         2.2.1 WM_COMMAND消息
           当用户点击菜单、button控件等时,系统会向窗体发送WM_COAMMD消息。


             WPARAM:HIWORD - 通知消息标识
                     LOWORD - 菜单项的ID号
             LPARAM:控件的句柄
         2.2.2 命令处理
            依据菜单项的ID号作对应处理。
            
       2.3 菜单项的状态
          2.3.1 WM_INITMENUPOPUP消息
            当用户点击菜单,显示弹出菜单之前,系统会向窗体发送WM_INITMENUPOPUP消息。
            WPARAM:是菜单句柄
            LPARAM:LOWORD - 菜单位置
                    HIWORD - 是否是系统菜单
          2.3.2 命令处理
            依据WPARAM的菜单句柄,使用MenuAPI函数,改动菜单状态。


             CheckMenuItem - 选择
             EnableMenuItem - 同意和禁止
             SetMenuItemInfo - 能够设置很多其它信息

    /* File : winMenu.cpp  
     * Auth : sjin  
     * Date : 20140706  
     * Mail : 413977243@qq.com  
     */    
        
    #include <Windows.h>    
    #include <stdio.h>
    
    
    HINSTANCE g_hInst   = NULL;
    HANDLE    g_hStdOut = NULL;
    BOOL      g_bCheckCut = FALSE;
    
    void OnCreate( HWND hWnd, UINT nMsg,
        WPARAM wParam, LPARAM lParam )
    {    //创建主菜单
        HMENU hMainMenu = CreateMenu( );
        //创建子菜单
        HMENU hFileMenu = CreatePopupMenu( );
        //添加菜单项 (&N) 添加快捷键ALT+N)
        AppendMenu( hFileMenu, MF_STRING|MF_CHECKED, 1001, "新建(&N)");
    	/*添加切割线的标示*/
        AppendMenu( hFileMenu, MF_SEPARATOR, 0, NULL );
        AppendMenu( hFileMenu, MF_STRING, 1002, "退出(&X)");
        AppendMenu( hMainMenu, MF_STRING|MF_POPUP, 
            (UINT)hFileMenu, "文件(&F)");
    
        HMENU hEditMenu = CreatePopupMenu( );
        AppendMenu( hEditMenu, MF_STRING, 1003, "剪切(&T)" );
    	/*添加切割线的标示*/
        AppendMenu( hEditMenu, MF_SEPARATOR, 0, NULL );
        AppendMenu( hEditMenu, MF_STRING, 1004, "拷贝(&C)" );
    	/*添加切割线的标示*/
        AppendMenu( hEditMenu, MF_SEPARATOR, 0, NULL );
        AppendMenu( hEditMenu, MF_STRING, 1005, "粘贴(&P)" );
        AppendMenu( hMainMenu, MF_STRING|MF_POPUP, 
            (UINT)hEditMenu, "编辑(&E)");
    
        HMENU hHelpMenu = CreatePopupMenu( );
        AppendMenu( hHelpMenu, MF_STRING, 1006, "帮助(&H)" );
    	/*添加切割线的标示*/
        AppendMenu( hHelpMenu, MF_SEPARATOR, 0, NULL );
        AppendMenu( hHelpMenu, MF_STRING, 1007, "关于(&A)" );
        AppendMenu( hMainMenu, MF_STRING|MF_POPUP, 
            (UINT)hHelpMenu, "帮助(&H)");
        //给窗体设置主菜单
        SetMenu( hWnd, hMainMenu );
    }
    
    void OnCommand( HWND hWnd, UINT nMsg, 
                   WPARAM wParam, LPARAM lParam )
    {
    	/*wParam: HIWORD: 通知消息的标示
    	 *        LOWORD:菜单项的ID
    	 * lParam: 控件的句柄
    	 *         对菜单来说这个为NULL
    	 *         对其它控件(button等)为句柄
    	 */
        UINT nID = LOWORD( wParam );
        CHAR szText[260] = {0};
        sprintf( szText, "OnCommand: %d
    ",
            nID );
        WriteConsole( g_hStdOut, szText,
            strlen(szText), NULL, NULL );
    
    	/*菜单项的处理*/
        switch( nID )
        {
        case 1002:/*退出*/
            PostQuitMessage( 0 );
            break;
        case 1003:
            g_bCheckCut = !g_bCheckCut;
            break;
        }
    }
    
    void OnInitMenuPopup( HWND hWnd, UINT nMsg,
        WPARAM wParam, LPARAM lParam )
    {
        CHAR szText[260] = { 0 };
        sprintf( szText, 
            "OnInitMenuPopup: WPARAM=%08X, LPARAM=%08X
    ", 
            wParam, lParam );
        WriteConsole( g_hStdOut, szText,
            strlen(szText), NULL, NULL );
    
        HMENU hMenu = (HMENU)wParam;
        if( TRUE == g_bCheckCut )
        {
    		/*CheckMenuItem是一个API函数,功能是复选或撤消复选指定的菜单栏目*/
            CheckMenuItem( hMenu, 1003, 
                MF_CHECKED|MF_BYCOMMAND );
        }
        else
        {
            CheckMenuItem( hMenu, 1003, 
                MF_UNCHECKED|MF_BYCOMMAND );
        }
    }
    
    LRESULT CALLBACK WndProc( HWND hWnd,
                              UINT nMsg,
                              WPARAM wParam,
                              LPARAM lParam )
    {
        switch( nMsg )
        {
        case WM_CREATE:
            OnCreate( hWnd, nMsg, wParam, lParam );
            break;
    
    		/*用户点击菜单、button控件等时,系统会想窗体发送WM_COAMMD消息*/
        case WM_COMMAND:
            OnCommand( hWnd, nMsg, wParam, lParam );
            break;
    
    		/*用户点击菜单,显示弹出菜单之前,系统会向窗体发送WM_INITMENUPOPUP消息
    		 *用于更新菜单项的状态
    		 */
        case WM_INITMENUPOPUP:
            OnInitMenuPopup( hWnd, nMsg, wParam, lParam );
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;
        }
        return DefWindowProc( hWnd, nMsg,
            wParam, lParam );
    }
    
    BOOL RegisterWnd( LPSTR pszClassName )
    {
        WNDCLASSEX wce = { 0 };
        wce.cbSize        = sizeof( wce );
        wce.cbClsExtra    = 0;
        wce.cbWndExtra    = 0;
        wce.hbrBackground = HBRUSH(COLOR_WINDOW);
        wce.hCursor       = NULL;
        wce.hIcon          = NULL;
        wce.hIconSm       = NULL;
        wce.hInstance     = g_hInst;
        wce.lpfnWndProc   = WndProc;
        wce.lpszClassName = pszClassName;
        wce.lpszMenuName  = NULL;
        wce.style         = CS_VREDRAW|CS_HREDRAW;
    
        ATOM nAtom = RegisterClassEx( &wce );
        if( 0 == nAtom )
        {
            return FALSE;
        }
        return TRUE;
    }
    
    HWND CreateWnd( LPSTR pszClassName )
    {
        HWND hWnd = CreateWindowEx( 0,
            pszClassName, "MyWnd", 
            WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, NULL, NULL, 
            g_hInst, 0 );
        return hWnd;
    }
    
    void DisplayWnd( HWND hWnd )
    {
        ShowWindow( hWnd, SW_SHOW );
        UpdateWindow( hWnd );
    }
    
    void Message( )
    {
        MSG msg = {0};
        while ( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }
    
    void NewConsole( )
    {
        AllocConsole( );
        g_hStdOut = 
            GetStdHandle( STD_OUTPUT_HANDLE );
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
        NewConsole( );
        g_hInst = hInstance;
        RegisterWnd( "MYWND_MENU" );
        HWND hWnd = CreateWnd( "MYWND_MENU" );
        DisplayWnd( hWnd );
        Message( );
        return 0;
    }

    三 系统菜单

      1 运行系统提供的窗体命令。比如最大化、关闭等命令。本质上和普通菜单一样,所以我们也能够在程序中使用这个菜单
        
      2 系统菜单的使用
        2.1 获取系统菜单
           GetSystemMenu

     HMENU GetSystemMenu(
        HWND hWnd, //要获取的窗体句柄
      BOOL bRevert  //获取时重置标示
     );

        bRevert: TRUE 重置 FLASE 不重置
        当Revert为TRUE时。会将菜单又一次置成默认的状态,并返回菜单句柄。假设为FALSE,菜单项不重置,获取到当前系统菜单的状态。


        
        2.2 改动系统菜单,比如添加、删除
           2.2.1 AppednMenu
           2.2.2 InsertMenu 
             比AppednMenu添加了一个插入菜单项的位置或ID。
           2.2.3 删除菜单项

      BOOL RemoveMenu( //
        HMENU hMenu, //菜单句柄
        UINT uPosition,//菜单项的位置或ID
        UINT uFlags );//菜单项的位置或ID的标示。

        uFlags为MF_BYCOMMAND, uPosition为菜单ID
        uFlags为MF_BYPOSITION,uPosition为菜单位置

        2.3 系统菜单的命令响应
           系统菜单的命令响应。是在WM_SYSCOMMAND中。


           WPARAM - LOWORD(wParam)为添加的菜单的ID

    复制代码
         int nID = LOWORD( wParam );
        switch( nID )
        {
        case 1001:
          //...
            break;
        }
    复制代码

    /* File : winMenu.cpp   
     * Auth : sjin   
     * Date : 20140706   
     * Mail : 413977243@qq.com   
     */      
          
    #include <Windows.h>      
    #include <stdio.h> 
    
    HINSTANCE g_hInst   = NULL;
    HANDLE    g_hStdOut = NULL;
    
    void OnCreate( HWND hWnd, UINT nMsg, 
                  WPARAM wParam, LPARAM lParam )
    {    
    	/* 获取系统菜单
    	 * HMENU GetSystemMenu(
    	 *    HWND hWnd, //要获取的窗体句柄
         *    BOOL bRevert  //获取时重置标示
         *   );
    	 *   bRevert : TRUE时,菜单会重置为默认状态
    	 *             FALSE: 菜单不重置获得当前系统的菜单状态
    	 */
        HMENU hSysMenu = GetSystemMenu( hWnd, FALSE );
        /*删除菜单项
    	 * BOOL RemoveMenu( //
    	 *		 HMENU hMenu, //菜单句柄
         *       UINT uPosition,//菜单项的位置或ID
         *        UINT uFlags );//菜单项的位置或ID的标示
    	 *   uFlags为MF_BYCOMMAND, uPosition为菜单ID
         *   uFlags为MF_BYPOSITION,uPosition为菜单位置
    	 */
        RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
        RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
        RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
        RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
        RemoveMenu( hSysMenu, 0, MF_BYPOSITION );
        // 添加菜单项
        InsertMenu( hSysMenu, 0, MF_BYPOSITION|MF_STRING,
            1001, "測试1" );
        InsertMenu( hSysMenu, 1, MF_BYPOSITION|MF_STRING,
            1002, "測试2" );
    }
    
    void OnSysCommand( HWND hWnd, UINT nMsg,
                       WPARAM wParam, LPARAM lParam )
    {
        CHAR szText[260] = { 0 };
        sprintf( szText,
            "OnSysCommand: WPARAM=%08X,LPARAM=%08X
    ",
            wParam, lParam );
        WriteConsole( g_hStdOut, szText, 
            strlen(szText), NULL, NULL );
    
        int nID = LOWORD( wParam );
        switch( nID )
        {
        case 1001:
            MessageBox( NULL, "Hello 1001", "SysMenu", MB_CANCELTRYCONTINUE );
            break;
        case 1002:
            MessageBox( NULL, "Hello 1002",  "SysMenu", MB_OK );
            break;
    	default:
    		break;
        }
    }
    
    LRESULT CALLBACK WndProc( HWND   hWnd, 
                              UINT   nMsg,
                              WPARAM wParam,
                              LPARAM lParam )
    {
        switch( nMsg )
        {
        case WM_CREATE:
            OnCreate( hWnd, nMsg, wParam, lParam );
            break;
        case WM_SYSCOMMAND:/*系统菜单命令响应*/
            OnSysCommand( hWnd, nMsg, wParam, lParam );
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;
        }
        return DefWindowProc( hWnd, nMsg,
            wParam, lParam );
    }
    
    BOOL RegisterWnd( LPSTR pszClassName )
    {
        WNDCLASSEX wce = { 0 };
        wce.cbSize        = sizeof( wce );
        wce.cbClsExtra    = 0;
        wce.cbWndExtra    = 0;
        wce.hbrBackground = HBRUSH(COLOR_WINDOW);
        wce.hCursor       = NULL;
        wce.hIcon         = NULL;
        wce.hIconSm       = NULL;
        wce.hInstance     = g_hInst;
        wce.lpfnWndProc   = WndProc;
        wce.lpszClassName = pszClassName;
        wce.lpszMenuName  = NULL;
        wce.style         = CS_HREDRAW|CS_VREDRAW;
    
        ATOM nAtom = RegisterClassEx( &wce );
        if( 0 ==  nAtom )
        {
            return FALSE;
        }
    
        return TRUE;
    }
    
    HWND CreateWnd( LPSTR pszClassName )
    {
        HWND hWnd = CreateWindowEx( 0,
            pszClassName, "MyWnd", 
            WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, NULL, NULL, g_hInst,
            NULL );
        return hWnd;
    }
    
    void DisplayWnd( HWND hWnd )
    {
        ShowWindow( hWnd, SW_SHOW );
        UpdateWindow( hWnd );
    }
    
    void Message( )
    {
        MSG msg = { 0 };
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }
    
    void NewConsole( )
    {
        AllocConsole( );
        g_hStdOut = 
            GetStdHandle( STD_OUTPUT_HANDLE );
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
        NewConsole( );
        g_hInst = hInstance;
        RegisterWnd( "MYWND" );
        HWND hWnd = CreateWnd( "MYWND" );
        DisplayWnd( hWnd );
        Message( );
        return 0;
    }


  • 相关阅读:
    zhanwei
    站位
    Web前端开发:SQL Jsp小项目(二)------添加修改
    Web前端开发:SQL Jsp小项目(一)
    JDBC(用Eclipse操作数据库Oracle)的基础操作集合
    Thread多线程stopSleep顺序问题
    IO流详解之代码详解
    IO流详解(半教材类型)
    用JQuery编写textarea,input,checkbox,select
    Java编写ArrayBasic制作一个简单的酒店管理系统
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7255972.html
Copyright © 2011-2022 走看看