走进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\n";
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\n";
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
}
break;
case 1001:
{
CHAR szText[] = "1001: Hello Timer\n";
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
}
break;
case 1002:/*1002 设置对应的处理函数,不会在这里调用*/
{
CHAR szText[] = "1002: Hello Timer\n";
WriteConsole( g_hStdOut, szText,
strlen(szText), NULL, NULL );
}
break;
default:
{
CHAR szText[260] = {0};
sprintf( szText, "%d: Hello Timer\n",
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......:\n";
/*将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\n",
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\n",
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\n",
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;
}
走进windows编程的世界-----消息处理函数(3)的更多相关文章
- 走进windows编程的世界-----消息处理函数(1)
Win32消息机制 过程驱动:程序是依照我们预先定义好的顺序运行.每运行一步,下一步都已经依照预定的顺序 继续运行,直至程序结束. 事件驱动:程序的运行顺序是无序的.某个时间点所运行的 ...
- 走进windows编程的世界-----消息处理函数(2)
一 WM_PAINT消息 1 WM_PAINT的产生 因为窗体的互相覆盖等,产生须要绘制的区域,那么会产生WM_PAINT消息. 普通情况下,不直接发送WM_PAINT消息,通过API声明须要 ...
- 走进windows编程的世界-----入门篇
1 Windows编程基础 1.1Win32应用程序基本类型 1) 控制台程序 不须要完好的windows窗体,能够使用DOS窗体方式显示 2) Win32窗体程序 包括窗体的程序,能够通过窗 ...
- 走进windows编程的世界-----画图相关
Windows画图 1 图形绘制 1.1 图形绘制的方式 获取到画图句柄-设备描写叙述表(DC),使用对应的画图的API,在设备上绘制图形. 1.2 颜色 ...
- 走进windows编程的世界-----对话框、文本框、button
1 对话框的分类 2 对话框的基本使用方式 3 对话框资源 4 有模式对话框的使用 int DialogBox( HINSTANCE hInstance, LPCTSTR lpTemplate, ...
- 走进windows编程的世界-----窗体的注冊及创建
1 窗体注冊和创建 1.1WIN32 窗体程序创建步骤 1.WinMain入口函数的定义 2.WindowProc函数的定义 3.注冊窗体类 RegisterClass.RegisterClass ...
- 走进windows编程的世界-----windows进程
Windows进程 1 Windows进程 进程是一个容器,包括了一个应用程序实例的各种资源.Windows多任务的操作系统,因此能够同一时候运行多个进程. 2 Windows进程的 ...
- [C#] 走进异步编程的世界 - 在 GUI 中执行异步操作
走进异步编程的世界 - 在 GUI 中执行异步操作 [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5877042.html 序 这是继<开始接 ...
- 走进异步编程的世界 - 在 GUI 中执行异步操作
转载:https://www.cnblogs.com/liqingwen/p/5877042.html 走进异步编程的世界 - 在 GUI 中执行异步操作 [博主]反骨仔 [原文地址]http://w ...
随机推荐
- 关于yii2 的db log 日志 错误处理errorHandler
log 通过配置Web.config来完成 1 数据库增加 ‘前缀_log’表 2 配置Web.config 'bootstrap' => ['log'], 'components' => ...
- Android studio配置使debug签名和release签名一致
在module的build.gradle中添加 android { //重要部分 signingConfigs { release { keyAlias 'jxt' keyPassword '1234 ...
- HDU 1114 【完全背包裸题】
Piggy-Bank Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- Python的功能模块[2] -> abc -> 利用 abc 建立抽象基类
abc模块 / abc Module 在定义抽象方法时,为了在初始化阶段就检测是否对抽象方法进行了重定义,Python 提供了 abc 模块. from abc import ABCMeta, abs ...
- java的IO,AIO简单对比
以下内容转载lzzzl Channel 通道 Buffer 缓冲区 Selector 选择器 其中Channel对应以前的流,Buffer不是什么新东西,Selector是因为nio可以使用异步的非堵 ...
- uvalive4108(线段树)
uvalive4108 题意 按顺序给出 n 个矩形,每给出一个矩形,统计它在多长的部分是最高的,并把这个长度称为该矩形的覆盖度,求最后总的覆盖度(每次得到的矩形的覆盖度之和) 分析 线段树.用两个数 ...
- bzoj2301(莫比乌斯反演)
bzoj2301 题意 求区间 [a, b] 和 区间 [c, d] 有多少对数 (x, y) 使得 gcd(x, y) = k . 分析 参考ppt 参考blog 考虑用容斥分成四次查询, 对于每次 ...
- 韩国研发AI武器遭抵制,武器自带“头脑”将多可怕
禁止自主武器的开发,事实上并不妨碍人工智能技术的发展,也不妨碍其被正常用于军事领域,其中的关键就在于,人类是否拥有控制权,能否在关键时刻对其进行关闭. 文 |郑伟彬 转自新京报专栏 4月4日,全球超过 ...
- linux64位使用xampp及常见问题
linux64位使用xampp及常见问题 换上ubntu9.10 64位,作为web工作者来说apache.php.mysql都必要安装的,在win里习惯了xampp,不是服务器为什么非要一个一个装呢 ...
- 在Android App中集成Google登录
技术文章 来源:码农网 发布:2016-09-19 浏览:194 摘要:今天,几乎所有的web和移动app都自带谷歌和Facebook登录,这对app开发者和用户来说是一个非常有用的功能,因为几乎每个 ...