二 定时器消息

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)的更多相关文章

  1. 走进windows编程的世界-----消息处理函数(1)

    Win32消息机制     过程驱动:程序是依照我们预先定义好的顺序运行.每运行一步,下一步都已经依照预定的顺序 继续运行,直至程序结束.     事件驱动:程序的运行顺序是无序的.某个时间点所运行的 ...

  2. 走进windows编程的世界-----消息处理函数(2)

    一 WM_PAINT消息 1 WM_PAINT的产生   因为窗体的互相覆盖等,产生须要绘制的区域,那么会产生WM_PAINT消息.   普通情况下,不直接发送WM_PAINT消息,通过API声明须要 ...

  3. 走进windows编程的世界-----入门篇

    1   Windows编程基础 1.1Win32应用程序基本类型 1)  控制台程序 不须要完好的windows窗体,能够使用DOS窗体方式显示 2)  Win32窗体程序 包括窗体的程序,能够通过窗 ...

  4. 走进windows编程的世界-----画图相关

    Windows画图 1 图形绘制      1.1 图形绘制的方式      获取到画图句柄-设备描写叙述表(DC),使用对应的画图的API,在设备上绘制图形.          1.2 颜色     ...

  5. 走进windows编程的世界-----对话框、文本框、button

    1 对话框的分类  2 对话框的基本使用方式  3 对话框资源  4 有模式对话框的使用 int DialogBox( HINSTANCE hInstance, LPCTSTR lpTemplate, ...

  6. 走进windows编程的世界-----窗体的注冊及创建

    1   窗体注冊和创建 1.1WIN32 窗体程序创建步骤 1.WinMain入口函数的定义 2.WindowProc函数的定义 3.注冊窗体类 RegisterClass.RegisterClass ...

  7. 走进windows编程的世界-----windows进程

    Windows进程  1 Windows进程    进程是一个容器,包括了一个应用程序实例的各种资源.Windows多任务的操作系统,因此能够同一时候运行多个进程.      2 Windows进程的 ...

  8. [C#] 走进异步编程的世界 - 在 GUI 中执行异步操作

    走进异步编程的世界 - 在 GUI 中执行异步操作 [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5877042.html 序 这是继<开始接 ...

  9. 走进异步编程的世界 - 在 GUI 中执行异步操作

    转载:https://www.cnblogs.com/liqingwen/p/5877042.html 走进异步编程的世界 - 在 GUI 中执行异步操作 [博主]反骨仔 [原文地址]http://w ...

随机推荐

  1. centos6.6部署mysql mmm高可用架构

    一.环境简述 1.工作逻辑图 2.MySQL-MMM优缺点 优点:高可用性,扩展性好,出现故障自动切换,对于主主同步,在同一时间只提供一台数据库写操作,保证的数据的一致性. 缺点:Monitor节点是 ...

  2. ActiveMQ StartUp

    从http://activemq.apache.org/activemq-5132-release.html 下载 解压 从apache-activemq-5.13.2\bin\win64\wrapp ...

  3. [thinkphp] MD!! 数组构造的好好的,硬是有一个值无法写入数据库

    我都要抓狂了,buildsql()方法又用不了,最后决定看runtime里面的文件.先删掉所有的runtime,然后提交一次,就可以在runtime里面看到对应解析后的文件,这样应该可以知道问题在哪. ...

  4. Python_Tips[2] -> 函数延后估值及字节码分析

    函数延后估值及字节码分析 在一个循环中定义了函数 f 但是并未对其进行调用,在循环结束后调用,此时i值为3故最终3个函数输出均为9.而非1, 4, 9. 这是由于在定义闭包函数 f 时,传入变量 i, ...

  5. [Math Review] Statistics Basic: Estimation

    Two Types of Estimation One of the major applications of statistics is estimating population paramet ...

  6. [Python Cookbook] Pandas: 3 Ways to define a DataFrame

    Using Series (Row-Wise) import pandas as pd purchase_1 = pd.Series({'Name': 'Chris', 'Item Purchased ...

  7. apache mod_speling.so 忽略URL大小写(自动纠错)

    apache mod_speling.so 忽略URL大小写(自动纠错) 打开配置文件  httpd.conf 加入 LoadModule speling_module modules/mod_spe ...

  8. Maven创建多模块项目(包括依赖版本号的统一更新)

    0.多项目工程的文件夹及依赖关系 bus-core-api为公共项目,app-web-ui依赖bus-core-api,app-desktop-ui依赖bus-core-api 1.创建一个父Mave ...

  9. 为Chrome多账户添加单独的快捷方式

    Chrome的多账户功能非常好用,每个账户都有自己的独立的收藏夹.个人设置等.但是,当你要使用的账户不是默认账户时,必须经过一个切换的操作.本文将简单的介绍一个如何各账户添加快捷方式,从而实现直接登陆 ...

  10. 设计模式之状态模式(PHP实现)

    github地址:https://github.com/ZQCard/design_pattern /** * 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计 ...