Windows多文档窗口编程中,需要注意的以下几点:

1、主窗口与文档窗口之间还有一个Client Window。

2、创建文档窗口。通常认为创建子窗口就用CreateWindow,但是MDI中创建文档窗口时,用的是发送消息的方式。具体的CreateWindow的工作由Client Window来完成。该消息是WM_MDICREATE。

3、主菜单的变化。切换到不同的文档窗口时,主菜单会随文档窗口的类型、内容等变化。文档子窗口是通过处理WM_MDIACTIVATE消息完成的。

4、主窗口默认的消息处理函数不是DefWindowProc,而是DefFrameProc。文档窗口和主窗口一样,默认的消息处理函数也变了,是DefMDIChildProc。它们的原型分别是

LRESULT DefFrameProc(      
    HWND hWnd,
    HWND hWndMDIClient,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
);
LRESULT DefMDIChildProc(
    HWND hWnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
);
<<Windows Programming>>第19章源码如下:
MDIDEMO.H
/*-----------------------
MDIDEMO.H header file
-----------------------*/ #define EXPORT __declspec (dllexport) #define INIT_MENU_POS 0
#define HELLO_MENU_POS 2
#define RECT_MENU_POS 1 #define IDM_NEWHELLO 10
#define IDM_NEWRECT 11
#define IDM_CLOSE 12
#define IDM_EXIT 13 #define IDM_BLACK 20
#define IDM_RED 21
#define IDM_GREEN 22
#define IDM_BLUE 23
#define IDM_WHITE 24 #define IDM_TILE 30
#define IDM_CASCADE 31
#define IDM_ARRANGE 32
#define IDM_CLOSEALL 33 #define IDM_FIRSTCHILD 100
MDIDEMO.C
/*--------------------------------------------------------
MDIDEMO.C -- Multiple Document Interface Demonstration
(c) Charles Petzold, 1996
--------------------------------------------------------*/ #include <windows.h>
#include <stdlib.h>
#include "mdidemo.h" LRESULT CALLBACK FrameWndProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL CALLBACK CloseEnumProc (HWND, LPARAM) ;
LRESULT CALLBACK HelloWndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK RectWndProc (HWND, UINT, WPARAM, LPARAM) ; // structure for storing data unique to each Hello child window
typedef struct tagHELLODATA{
UINT iColor ;
COLORREF clrText ;
}HELLODATA, *LPHELLODATA ; // structure for storing data unique to each Rect child window
typedef struct tagRECTDATA{
short cxClient ;
short cyClient ;
}RECTDATA, *LPRECTDATA ; // global variables
char szFrameClass[] = "MdiFrame" ;
char szHelloClass[] = "MdiHelloChild" ;
char szRectClass[] = "MdiRectChild" ;
HINSTANCE hInst ;
HMENU hMenuInit, hMenuHello, hMenuRect ;
HMENU hMenuInitWindow, hMenuHelloWindow, hMenuRectWindow ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HACCEL hAccel ;
HWND hwndFrame, hwndClient ;
MSG msg ;
WNDCLASSEX wndclass ; hInst = hInstance ; if (!hPrevInstance)
{
// Register the frame window class
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = FrameWndProc ;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + ) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szFrameClass ;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; RegisterClassEx (&wndclass) ; // Register the Hello child window class
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = HelloWndProc ;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = sizeof (HANDLE) ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szHelloClass ;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; RegisterClassEx (&wndclass) ; // Register the Rect child window class
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = RectWndProc ;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = sizeof (HANDLE) ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szRectClass ;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; RegisterClassEx (&wndclass) ;
}
// Obtain handles to three possible menus & submenus
hMenuInit = LoadMenu (hInst, "MdiMenuInit") ;
hMenuHello = LoadMenu (hInst, "MdiMenuHello") ;
hMenuRect = LoadMenu (hInst, "MdiMenuRect") ; hMenuInitWindow = GetSubMenu (hMenuInit, INIT_MENU_POS) ;
hMenuHelloWindow = GetSubMenu (hMenuHello, HELLO_MENU_POS) ;
hMenuRectWindow = GetSubMenu (hMenuRect, RECT_MENU_POS) ; // Load accelerator table
hAccel = LoadAccelerators (hInst, "MdiAccel") ; // Create the frame window
hwndFrame = CreateWindow (szFrameClass, "MDI Demonstration",
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, hMenuInit, hInstance, NULL) ; hwndClient = GetWindow (hwndFrame, GW_CHILD) ; ShowWindow (hwndFrame, iCmdShow) ;
UpdateWindow (hwndFrame) ; // Enter the modified message loop
while (GetMessage (&msg, NULL, , ))
{
if (!TranslateMDISysAccel (hwndClient, &msg) &&
!TranslateAccelerator (hwndFrame, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
// Clean up by deleting unattached menus
DestroyMenu (hMenuHello) ;
DestroyMenu (hMenuRect) ; return msg.wParam ;
} LRESULT CALLBACK FrameWndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hwndClient ;
CLIENTCREATESTRUCT clientcreate ;
HWND hwndChild ;
MDICREATESTRUCT mdicreate ; switch (iMsg)
{
case WM_CREATE : // Create the client window
clientcreate.hWindowMenu = hMenuInitWindow ;
clientcreate.idFirstChild = IDM_FIRSTCHILD ;
hwndClient = CreateWindow ("MDICLIENT", NULL,
WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
, , , , hwnd, (HMENU) , hInst,
(LPSTR) &clientcreate) ;
return ; case WM_COMMAND :
switch (wParam)
{
case IDM_NEWHELLO : // Create a Hello child window
mdicreate.szClass = szHelloClass ;
mdicreate.szTitle = "Hello" ;
mdicreate.hOwner = hInst ;
mdicreate.x = CW_USEDEFAULT ;
mdicreate.y = CW_USEDEFAULT ;
mdicreate.cx = CW_USEDEFAULT ;
mdicreate.cy = CW_USEDEFAULT ;
mdicreate.style = ;
mdicreate.lParam = ; hwndChild = (HWND) SendMessage (hwndClient,
WM_MDICREATE, ,
(LPARAM) (LPMDICREATESTRUCT) &mdicreate) ;
return ; case IDM_NEWRECT : // Create a Rect child window
mdicreate.szClass = szRectClass ;
mdicreate.szTitle = "Rectangles" ;
mdicreate.hOwner = hInst ;
mdicreate.x = CW_USEDEFAULT ;
mdicreate.y = CW_USEDEFAULT ;
mdicreate.cx = CW_USEDEFAULT ;
mdicreate.cy = CW_USEDEFAULT ;
mdicreate.style = ;
mdicreate.lParam = ; hwndChild = (HWND) SendMessage (hwndClient,
WM_MDICREATE, ,
(LPARAM) (LPMDICREATESTRUCT) &mdicreate) ;
return ; case IDM_CLOSE : // Close the active window
hwndChild = (HWND) SendMessage (hwndClient,
WM_MDIGETACTIVE, , ) ; if (SendMessage (hwndChild, WM_QUERYENDSESSION, , ))
SendMessage (hwndClient, WM_MDIDESTROY,
(WPARAM) hwndChild, ) ;
return ; case IDM_EXIT : // Exit the program
SendMessage (hwnd, WM_CLOSE, , ) ;
return ; // messages for arranging windows
case IDM_TILE :
SendMessage (hwndClient, WM_MDITILE, , ) ;
return ; case IDM_CASCADE :
SendMessage (hwndClient, WM_MDICASCADE, , ) ;
return ; case IDM_ARRANGE :
SendMessage (hwndClient, WM_MDIICONARRANGE, , ) ;
return ; case IDM_CLOSEALL : // Attempt to close all children
EnumChildWindows (hwndClient, &CloseEnumProc, ) ;
return ; default : // Pass to active child...
hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, , );
if (IsWindow (hwndChild))
SendMessage (hwndChild, WM_COMMAND, wParam, lParam) ; break ; // ...and then to DefFrameProc
}
break ; case WM_QUERYENDSESSION :
case WM_CLOSE : // Attempt to close all children
SendMessage (hwnd, WM_COMMAND, IDM_CLOSEALL, ) ; if (NULL != GetWindow (hwndClient, GW_CHILD))
return ; break ; // I.e., call DefFrameProc case WM_DESTROY :
PostQuitMessage () ;
return ;
}
// Pass unprocessed messages to DefFrameProc (not DefWindowProc)
return DefFrameProc (hwnd, hwndClient, iMsg, wParam, lParam) ;
} BOOL CALLBACK CloseEnumProc (HWND hwnd, LPARAM lParam)
{
if (GetWindow (hwnd, GW_OWNER)) // Check for icon title
return ; SendMessage (GetParent (hwnd), WM_MDIRESTORE, (WPARAM) hwnd, ) ; if (!SendMessage (hwnd, WM_QUERYENDSESSION, , ))
return ; SendMessage (GetParent (hwnd), WM_MDIDESTROY, (WPARAM) hwnd, ) ;
return ;
} LRESULT CALLBACK HelloWndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static COLORREF clrTextArray[] = { RGB (, , ),
RGB (, , ),
RGB (, , ),
RGB ( , , ),
RGB (, , ) } ;
static HWND hwndClient, hwndFrame ;
HDC hdc ;
HMENU hMenu ;
LPHELLODATA lpHelloData ;
PAINTSTRUCT ps ;
RECT rect ; switch (iMsg)
{
case WM_CREATE :
// Allocate memory for window private data
lpHelloData = (LPHELLODATA) HeapAlloc (GetProcessHeap (),
HEAP_ZERO_MEMORY,
sizeof (HELLODATA)) ;
lpHelloData->iColor = IDM_BLACK ;
lpHelloData->clrText = RGB (, , ) ;
SetWindowLong (hwnd, , (long) lpHelloData) ; // Save some window handles
hwndClient = GetParent (hwnd) ;
hwndFrame = GetParent (hwndClient) ;
return ; case WM_COMMAND :
switch (wParam)
{
case IDM_BLACK :
case IDM_RED :
case IDM_GREEN :
case IDM_BLUE :
case IDM_WHITE :
// Change the text color
lpHelloData = (LPHELLODATA) GetWindowLong (hwnd, ) ; hMenu = GetMenu (hwndFrame) ; CheckMenuItem (hMenu, lpHelloData->iColor,
MF_UNCHECKED) ;
lpHelloData->iColor = wParam ;
CheckMenuItem (hMenu, lpHelloData->iColor,
MF_CHECKED) ; lpHelloData->clrText =
clrTextArray[wParam - IDM_BLACK] ; InvalidateRect (hwnd, NULL, FALSE) ;
}
return ; case WM_PAINT :
// Paint the window
hdc = BeginPaint (hwnd, &ps) ; lpHelloData = (LPHELLODATA) GetWindowLong (hwnd, ) ;
SetTextColor (hdc, lpHelloData->clrText) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, "Hello, World!", -, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ;
return ; case WM_MDIACTIVATE :
// Set the Hello menu if gaining focus
if (lParam == (LPARAM) hwnd)
SendMessage (hwndClient, WM_MDISETMENU,
(WPARAM) hMenuHello, (LPARAM) hMenuHelloWindow) ; // Check or uncheck menu item
lpHelloData = (LPHELLODATA) GetWindowLong (hwnd, ) ;
CheckMenuItem (hMenuHello, lpHelloData->iColor,
(lParam == (LPARAM) hwnd) ? MF_CHECKED : MF_UNCHECKED) ; // Set the Init menu if losing focus
if (lParam != (LPARAM) hwnd)
SendMessage (hwndClient, WM_MDISETMENU, (WPARAM) hMenuInit,
(LPARAM) hMenuInitWindow) ; DrawMenuBar (hwndFrame) ;
return ; case WM_QUERYENDSESSION :
case WM_CLOSE :
if (IDOK != MessageBox (hwnd, "OK to close window?", "Hello",
MB_ICONQUESTION | MB_OKCANCEL))
return ; break ; // I.e., call DefMDIChildProc case WM_DESTROY :
lpHelloData = (LPHELLODATA) GetWindowLong (hwnd, ) ;
HeapFree (GetProcessHeap (), , lpHelloData) ;
return ;
}
// Pass unprocessed message to DefMDIChildProc
return DefMDIChildProc (hwnd, iMsg, wParam, lParam) ;
} LRESULT CALLBACK RectWndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hwndClient, hwndFrame ;
HBRUSH hBrush ;
HDC hdc ;
LPRECTDATA lpRectData ;
PAINTSTRUCT ps ;
int xLeft, xRight, yTop, yBottom ;
short nRed, nGreen, nBlue ; switch (iMsg)
{
case WM_CREATE :
// Allocate memory for window private data lpRectData = (LPRECTDATA) HeapAlloc (GetProcessHeap (),
HEAP_ZERO_MEMORY,
sizeof (RECTDATA)) ; SetWindowLong (hwnd, , (long) lpRectData) ; // Start the timer going SetTimer (hwnd, , , NULL) ; // Save some window handles hwndClient = GetParent (hwnd) ;
hwndFrame = GetParent (hwndClient) ;
return ; case WM_SIZE : // If not minimized, save the window size if (wParam != SIZE_MINIMIZED)
{
lpRectData = (LPRECTDATA) GetWindowLong (hwnd, ) ; lpRectData->cxClient = LOWORD (lParam) ;
lpRectData->cyClient = HIWORD (lParam) ;
} break ; // WM_SIZE must be processed by DefMDIChildProc case WM_TIMER : // Display a random rectangle lpRectData = (LPRECTDATA) GetWindowLong (hwnd, ) ; xLeft = rand () % lpRectData->cxClient ;
xRight = rand () % lpRectData->cxClient ;
yTop = rand () % lpRectData->cyClient ;
yBottom = rand () % lpRectData->cyClient ;
nRed = rand () & ;
nGreen = rand () & ;
nBlue = rand () & ; hdc = GetDC (hwnd) ;
hBrush = CreateSolidBrush (RGB (nRed, nGreen, nBlue)) ;
SelectObject (hdc, hBrush) ; Rectangle (hdc, min (xLeft, xRight), min (yTop, yBottom),
max (xLeft, xRight), max (yTop, yBottom)) ; ReleaseDC (hwnd, hdc) ;
DeleteObject (hBrush) ;
return ; case WM_PAINT : // Clear the window InvalidateRect (hwnd, NULL, TRUE) ;
hdc = BeginPaint (hwnd, &ps) ;
EndPaint (hwnd, &ps) ;
return ; case WM_MDIACTIVATE : // Set the appropriate menu
if (lParam == (LPARAM) hwnd)
SendMessage (hwndClient, WM_MDISETMENU, (WPARAM) hMenuRect,
(LPARAM) hMenuRectWindow) ;
else
SendMessage (hwndClient, WM_MDISETMENU, (WPARAM) hMenuInit,
(LPARAM) hMenuInitWindow) ; DrawMenuBar (hwndFrame) ;
return ; case WM_DESTROY :
lpRectData = (LPRECTDATA) GetWindowLong (hwnd, ) ;
HeapFree (GetProcessHeap (), , lpRectData) ;
KillTimer (hwnd, ) ;
return ;
}
// Pass unprocessed message to DefMDIChildProc
return DefMDIChildProc (hwnd, iMsg, wParam, lParam) ;
}
MDIDEMO.RC
/*----------------------------
MDIDEMO.RC resource script
----------------------------*/ #include <windows.h>
#include "mdidemo.h" MdiMenuInit MENU
{
POPUP "&File"
{
MENUITEM "New &Hello", IDM_NEWHELLO
MENUITEM "New &Rectangles", IDM_NEWRECT
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
}
} MdiMenuHello MENU
{
POPUP "&File"
{
MENUITEM "New &Hello", IDM_NEWHELLO
MENUITEM "New &Rectangles", IDM_NEWRECT
MENUITEM "&Close", IDM_CLOSE
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
}
POPUP "&Color"
{
MENUITEM "&Black", IDM_BLACK
MENUITEM "&Red", IDM_RED
MENUITEM "&Green", IDM_GREEN
MENUITEM "B&lue", IDM_BLUE
MENUITEM "&White", IDM_WHITE
}
POPUP "&Window"
{
MENUITEM "&Cascade\tShift+F5", IDM_CASCADE
MENUITEM "&Tile\tShift+F4", IDM_TILE
MENUITEM "Arrange &Icons", IDM_ARRANGE
MENUITEM "Close &All", IDM_CLOSEALL
}
} MdiMenuRect MENU
{
POPUP "&File"
{
MENUITEM "New &Hello", IDM_NEWHELLO
MENUITEM "New &Rectangles", IDM_NEWRECT
MENUITEM "&Close", IDM_CLOSE
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
}
POPUP "&Window"
{
MENUITEM "&Cascade\tShift+F5", IDM_CASCADE
MENUITEM "&Tile\tShift+F4", IDM_TILE
MENUITEM "Arrange &Icons", IDM_ARRANGE
MENUITEM "Close &All", IDM_CLOSEALL
}
} MdiAccel ACCELERATORS
{
VK_F5, IDM_CASCADE, VIRTKEY, SHIFT
VK_F4, IDM_TILE, VIRTKEY, SHIFT
}

Windows MDI(Multiple-Document Interface)的更多相关文章

  1. Single document interface和Multiple document interface

    https://en.wikipedia.org/wiki/Single_document_interface https://msdn.microsoft.com/en-us/library/b2k ...

  2. 使用多文档接口(Multiple Document Interface) 一

    原文地址msdn:https://msdn.microsoft.com/en-us/library/windows/desktop/ms644909(v=vs.85).aspx#creating_fr ...

  3. windows.onload和 document.ready区别

    在Jquery里面,我们可以看到两种写法:$(function(){}) 和$(document).ready(function(){}) 这两个方法的效果都是一样的,都是在dom文档树加载完之后执行 ...

  4. 浅谈windows.onload()与$(document).ready()

    浏览器加载完DOM后,会通过javascript为DOM元素添加事件,在javascript中,通常使用window.onload()方法. 在jquery中,则使用$(document).ready ...

  5. C# Winform学习---MDI窗体的设计,PictureBox控件(图片上一页下一页),Timer控件,MenuStrip控件

    一.MDI窗体的设计 1.MDI简介 MDI(Multiple Document Interface)就是所谓的多文档界面,与此对应就有单文档界面 (SDI), 它是微软公司从Windows 2.0下 ...

  6. C# 设置MDI子窗体只能弹出一个的方法

    Windows程序设计中的MDI(Multiple Document Interface)官方解释就是所谓的多文档界面,与此对应就有单文档界面 (SDI), 它是微软公司从Windows .0下的Mi ...

  7. MDI和在TabPage

    无奈的.net探索 MDI和在TabPage中增加Form分页? MDI(Multiple Document Interface)是一种在窗口中嵌套窗口的接口, 与之对应的是SDI(Single Do ...

  8. wx

    wx The classes in this module are the most commonly used classes for wxPython, which is why they hav ...

  9. MDI-设置子窗体只能弹出一个--单例模式

    不足之处,欢迎指正! 什么是MDI..我表示不知道的呢. MDI(Multiple Document Interface)就是所谓的多文档界面,与此对应就有单文档界面 (SDI), 它是微软公司从Wi ...

随机推荐

  1. 关于Net开发中一些SQLServer性能优化的建议

    一. ExecuteNonQuery和ExecuteScalar 对数据的更新不需要返回结果集,建议使用ExecuteNonQuery.由于不返回结果集可省掉网络数据传输.它仅仅返回受影响的行数.如果 ...

  2. usaco training 4.2.2 The Perfect Stall 最佳牛栏 题解

    The Perfect Stall题解 Hal Burch Farmer John completed his new barn just last week, complete with all t ...

  3. Spring中获取对象

    Spring是一个非常主流,而且是好用的框架.提供管理对象的容器,提供事务的支持,缓存,权限认证(往往不用).用来集成hibernate等.而管理对象的生命周期是其中一个非常重要的功能.在Spring ...

  4. Sql 2008R2 windows身份好用 ,sa身份不好用

    Sql server2008r2 安装完毕以后 windows身份验证好用,sa身份不好用,解决方法步骤如下: 1.首先用windows身份登录 2.SQL实例右键属性 3.安全性这一项 4.选择wi ...

  5. php使用flock阻塞写入文件和非阻塞写入文件的实例讲解

    php使用flock阻塞写入文件和非阻塞写入文件的实例讲解: 阻塞写入代码:(所有程序会等待上次程序执行结束才会执行,30秒会超时) <?php $file = fopen("test ...

  6. 浅谈游戏中BOSS设计的思路

    对于大多数游戏来说,BOSS在其设计上都有着不可替代的作用,也是玩家印象最为深刻的一部分.近期自己也有在做BOSS的设计工作,有一些心得想要分享一下: 1.明确BOSS的设计目的 在设计之初,我们一定 ...

  7. Mybatis JPA 代码构建

    前段时间了解到Spring JPA,感觉挺好用,但其依赖于Hibernate,本人看到Hibernate就头大(不是说Hibernate不好哈,而是进阶太难),于是做了一个迷你版的Mybatis JP ...

  8. ARM开发(3)基于STM32的矩阵键盘控制蜂鸣器

    一 矩阵键盘控制蜂鸣器原理:  1.1 本实验实现8*7矩阵键盘上按键控制蜂鸣器响.  1.2 实验思路:根据电路图原理,找出矩阵键盘行列所对应的引脚,赋予对应的按键值,然后控制蜂鸣器响.  1.3 ...

  9. 使用JavaScript开发跨平台的桌面应用

    任何可以使用JavaScript来编写的应用,最终会由JavaScript编写.--Atwood定律 Atwood's Law是Jeff Atwood在2007年提出的:"any appli ...

  10. Hibernate一对多实例

    本文向大家介绍Hibernate实例一对多的情况,可能好多人还不了解Hibernate实例一对多,没有关系,下面通过一个实例来帮助您理解Hibernate实例一对多,希望本文能教会你更多东西. 先看由 ...