第三篇:用SOUI能做什么?

时间:2021-12-17 23:25:39

SOUI-DEMO界面预览

在回答SOUI能做什么之前,先看看SVN中demo工程的界面截图:

第三篇:用SOUI能做什么?第三篇:用SOUI能做什么?第三篇:用SOUI能做什么?第三篇:用SOUI能做什么?第三篇:用SOUI能做什么?第三篇:用SOUI能做什么?第三篇:用SOUI能做什么?

使用SOUI实现上面的界面主要的工作全在配置几个XML文件,基本不需要写C++代码。(如何配置XML布局将在后续文章中讲解)

从零开始生成一个使用SOUI的应用程序

以SOUI的demo为例,我们看在SOUI中如何一步一步实现一个应用程序。

首先使用Win32应用程序向导生成一个空项目。

新建一个如demo.cpp文件,定义一个_tWinMain函数。

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpstrCmdLine*/, int /*nCmdShow*/)
{
  return 0;
}

在项目的包含目录中包含$(SOUIPATH)\soui\include;$(SOUIPATH)\utilities\include;这两个目录。同时在库依赖中增加soui.lib utilities.lib。

$(SOUIPATH)是从SVN签出的trunk的根目录,如果安装了soui下的应用程序向导会自动为系统增加这个环境变量。

做好上述准备工作后在工程目录下建立一个如uires的目录,用来存放程序中用到的资源文件,包括布局使用的图片及XML布局文件。

在该目录下应该至少有一个uires.idx文件。uires.idx是一个XML文件,它定义程序中用到的所有其它资源的类型及名称。

demo中使用的uires.xml如下:

 <?xml version="1.0" encoding="utf-8"?>
<resource>
<UIDEF>
<file name="xml_init" path="xml\init.xml" />
</UIDEF>
<ICON>
<file name="LOGO" path="image\img_logo.ico" />
</ICON>
<CURSOR>
<file name="ANI_ARROW" path="image\021.ani" />
<file name="CUR_TST" path="image\camera_capture.cur"/>
</CURSOR>
<LAYOUT>
<file name="maindlg" path="xml\dlg_main.xml" />
<file name="menu_test" path="xml\menu_test.xml" />
<file name="page_layout" path="xml\page_layout.xml" />
<file name="page_treebox" path="xml\page_treebox.xml" />
<file name="page_treectrl" path="xml\page_treectrl.xml" />
<file name="page_misc" path="xml\page_misc.xml" />
<file name="page_webkit" path="xml\page_webkit.xml" />
<file name="page_about" path="xml\page_about.xml" />
</LAYOUT>
<IMGX>
<file name="png_page_icons" path="image\page_icons.png" />
<file name="png_small_icons" path="image\small_icons.png" /> <file name="webbtn_back" path="image\webbtn_back.png" />
<file name="webbtn_forward" path="image\webbtn_forward.png" />
<file name="webbtn_refresh" path="image\webbtn_refresh.png" /> <file name="png_treeicon" path="image\TreeIcon.png"/>
<file name="png_menu_border" path="image\menuborder.png" /> <file name="png_vscroll" path="image\vscrollbar.png" /> <file name="png_tab_left" path="image\tab_left.png" />
<file name="png_tab_left_splitter" path="image\tab_left_splitter.png" />
<file name="png_tab_main" path="image\tab_main.png" />
<file name="btn_menu" path="image\btn_menu.png" />
</IMGX>
<GIF>
<file name="gif_horse" path="image\horse.gif"/>
<file name="gif_penguin" path="image\penguin.gif"/>
</GIF>
<rtf>
<file name="rtf_test" path="rtf\RTF测试.rtf"/>
</rtf>
<script>
<file name="lua_test" path="lua\test.lua"/>
</script>
<translator>
<file name="lang_cn" path="translation files\lang_cn.xml"/>
</translator>
</resource>

如上所示,该XML有一个resource的根节点,下面可以是任意定义的类型(ICON, BITMAP,CURSOR除外,它们是预定义的类型,不能修改类型名)。

每个类型下面定义有file元素,元素中有两个属性:name 及 path。

name即资源的名称,path即资源的路径。所有资源建议采用相对路径,即相对于uires.idx文件的路径。

在程序中通过type及name来引用资源。

下面开始填空:

 int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpstrCmdLine*/, int /*nCmdShow*/)
{
//必须要调用OleInitialize来初始化运行环境
HRESULT hRes = OleInitialize(NULL);
SASSERT(SUCCEEDED(hRes)); int nRet = ; //定义一组组件加载辅助对象
//SComLoader实现从DLL的指定函数创建符号SOUI要求的类COM组件。
SComLoader imgDecLoader;
SComLoader renderLoader;
SComLoader transLoader;
SComLoader scriptLoader;
SComLoader zipResLoader; //将程序的运行路径修改到demo所在的目录
TCHAR szCurrentDir[MAX_PATH]={};
GetModuleFileName( NULL, szCurrentDir, sizeof(szCurrentDir) );
LPTSTR lpInsertPos = _tcsrchr( szCurrentDir, _T('\\') );
_tcscpy(lpInsertPos,_T("\\..\\demo"));
SetCurrentDirectory(szCurrentDir); {
//定义一组类SOUI系统中使用的类COM组件
//CAutoRefPtr是一个SOUI系统中使用的智能指针类
CAutoRefPtr<IImgDecoderFactory> pImgDecoderFactory; //图片解码器,由imagedecoder-wid.dll模块提供
CAutoRefPtr<IRenderFactory> pRenderFactory; //UI渲染模块,由render-gdi.dll或者render-skia.dll提供
CAutoRefPtr<ITranslatorMgr> trans; //多语言翻译模块,由translator.dll提供
CAutoRefPtr<IScriptModule> pScriptLua; //lua脚本模块,由scriptmodule-lua.dll提供 BOOL bLoaded=FALSE;
int nType=MessageBox(GetActiveWindow(),_T("选择渲染类型:\n[yes]: Skia\n[no]:GDI\n[cancel]:Quit"),_T("select a render"),MB_ICONQUESTION|MB_YESNOCANCEL);
if(nType == IDCANCEL) return -;
//从各组件中显示创建上述组件对象
bLoaded=renderLoader.CreateInstance(nType==IDYES?COM_RENDER_SKIA:COM_RENDER_GDI,(IObjRef**)&pRenderFactory);
SASSERT_FMT(bLoaded,_T("load module [%s] failed!"),nType==IDYES?COM_RENDER_SKIA:COM_RENDER_GDI);
bLoaded=imgDecLoader.CreateInstance(COM_IMGDECODER,(IObjRef**)&pImgDecoderFactory);
SASSERT_FMT(bLoaded,_T("load module [%s] failed!"),COM_IMGDECODER);
bLoaded=transLoader.CreateInstance(COM_TRANSLATOR,(IObjRef**)&trans);
SASSERT_FMT(bLoaded,_T("load module [%s] failed!"),COM_TRANSLATOR);
//为渲染模块设置它需要引用的图片解码模块
pRenderFactory->SetImgDecoderFactory(pImgDecoderFactory);
//定义一个唯一的SApplication对象,SApplication管理整个应用程序的资源
SApplication *theApp=new SApplication(pRenderFactory,hInstance); //定义一人个资源提供对象,SOUI系统中实现了3种资源加载方式,分别是从文件加载,从EXE的资源加载及从ZIP压缩包加载
CAutoRefPtr<IResProvider> pResProvider;
#if (RES_TYPE == 0)//从文件加载
CreateResProvider(RES_FILE,(IObjRef**)&pResProvider);
if(!pResProvider->Init((LPARAM)_T("uires"),))
{
SASSERT();
return ;
}
#elif (RES_TYPE==1)//从EXE资源加载
CreateResProvider(RES_PE,(IObjRef**)&pResProvider);
pResProvider->Init((WPARAM)hInstance,);
#elif (RES_TYPE==2)//从ZIP包加载
bLoaded=zipResLoader.CreateInstance(COM_ZIPRESPROVIDER,(IObjRef**)&pResProvider);
SASSERT(bLoaded);
ZIPRES_PARAM param;
param.ZipFile(pRenderFactory, _T("uires.zip"));
bLoaded = pResProvider->Init((WPARAM)&param,);
SASSERT(bLoaded);
#endif
//将创建的IResProvider交给SApplication对象
theApp->AddResProvider(pResProvider); if(trans)
{//加载语言翻译包
theApp->SetTranslator(trans);
pugi::xml_document xmlLang;
if(theApp->LoadXmlDocment(xmlLang,_T("lang_cn"),_T("translator")))
{
CAutoRefPtr<ITranslator> langCN;
trans->CreateTranslator(&langCN);
langCN->Load(&xmlLang.child(L"language"),);//1=LD_XML
trans->InstallTranslator(langCN);
}
}
#ifdef DLL_SOUI
//加载LUA脚本模块,注意,脚本模块只有在SOUI内核是以DLL方式编译时才能使用。
bLoaded=scriptLoader.CreateInstance(COM_SCRIPT_LUA,(IObjRef**)&pScriptLua);
SASSERT_FMT(bLoaded,_T("load module [%s] failed!"),COM_SCRIPT_LUA);
if(pScriptLua)
{
theApp->SetScriptModule(pScriptLua);
size_t sz=pResProvider->GetRawBufferSize(_T("script"),_T("lua_test"));
if(sz)
{
CMyBuffer<char> lua;
lua.Allocate(sz);
pResProvider->GetRawBuffer(_T("script"),_T("lua_test"),lua,sz);
pScriptLua->executeScriptBuffer(lua,sz);
}
}
#endif//DLL_SOUI //向SApplication系统中注册由外部扩展的控件及SkinObj类
SWkeLoader wkeLoader;
if(wkeLoader.Init(_T("wke.dll")))
{
theApp->RegisterWndFactory(TplSWindowFactory<SWkeWebkit>());//注册WKE浏览器
}
theApp->RegisterWndFactory(TplSWindowFactory<SGifPlayer>());//注册GIFPlayer
theApp->RegisterSkinFactory(TplSkinFactory<SSkinGif>());//注册SkinGif
SSkinGif::Gdiplus_Startup(); //加载系统资源
HMODULE hSysResource=LoadLibrary(SYS_NAMED_RESOURCE);
if(hSysResource)
{
CAutoRefPtr<IResProvider> sysSesProvider;
CreateResProvider(RES_PE,(IObjRef**)&sysSesProvider);
sysSesProvider->Init((WPARAM)hSysResource,);
theApp->LoadSystemNamedResource(sysSesProvider);
} //加载全局资源描述XML
theApp->Init(_T("xml_init")); {
//创建并显示使用SOUI布局应用程序窗口,为了保存窗口对象的析构先于其它对象,把它们缩进一层。
CMainDlg dlgMain;
dlgMain.Create(GetActiveWindow(),,,,);
dlgMain.GetNative()->SendMessage(WM_INITDIALOG);
dlgMain.CenterWindow();
dlgMain.ShowWindow(SW_SHOWNORMAL);
nRet=theApp->Run(dlgMain.m_hWnd);
} //应用程序退出
delete theApp;
SSkinGif::Gdiplus_Shutdown(); } OleUninitialize();
return nRet;
}

main中用到一个类CMainDlg,该类是demo的主窗口,前面提供的界面截图都是由该类渲染出来。

下面我们看一下CMainDlg的实现:

maindlg.h

 /**
* Copyright (C) 2014-2050
* All rights reserved.
*
* @file MainDlg.h
* @brief
* @version v1.0
* @author SOUI group
* @date 2014/08/15
*
* Describe 主窗口实现
*/ #pragma once /**
* @class CMainDlg
* @brief 主窗口实现
*
* Describe 非模式窗口从SHostWnd派生,模式窗口从SHostDialog派生
*/
class CMainDlg : public SHostWnd
{
public: /**
* CMainDlg
* @brief 构造函数
* Describe 使用uires.idx中定义的maindlg对应的xml布局创建UI
*/
CMainDlg() : SHostWnd(_T("maindlg")),m_bLayoutInited(FALSE)
{
} protected:
//////////////////////////////////////////////////////////////////////////
// Window消息响应函数
LRESULT OnInitDialog(HWND hWnd, LPARAM lParam);
void OnDestory(); void OnClose()
{
AnimateHostWindow(,AW_CENTER|AW_HIDE);
PostMessage(WM_QUIT);
}
void OnMaximize()
{
GetNative()->SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE);
}
void OnRestore()
{
GetNative()->SendMessage(WM_SYSCOMMAND,SC_RESTORE);
}
void OnMinimize()
{
GetNative()->SendMessage(WM_SYSCOMMAND,SC_MINIMIZE);
} void OnSize(UINT nType, CSize size)
{
SetMsgHandled(FALSE); //这一行很重要,保证消息继续传递给SHostWnd处理,当然也可以用SHostWnd::OnSize(nType,size);代替,但是这里使用的方法更简单,通用
if(!m_bLayoutInited) return;
if(nType==SIZE_MAXIMIZED)
{
FindChildByID()->SetVisible(TRUE);
FindChildByID()->SetVisible(FALSE);
}else if(nType==SIZE_RESTORED)
{
FindChildByID()->SetVisible(FALSE);
FindChildByID()->SetVisible(TRUE);
}
} int OnCreate(LPCREATESTRUCT lpCreateStruct);
void OnShowWindow(BOOL bShow, UINT nStatus); //DUI菜单响应函数
void OnCommand(UINT uNotifyCode, int nID, HWND wndCtl); protected:
//////////////////////////////////////////////////////////////////////////
// SOUI事件处理函数
//演示屏蔽指定edit控件的右键菜单
BOOL OnEditMenu(CPoint pt)
{
return TRUE;
} //按钮控件的响应
void OnBtnSelectGIF();
void OnBtnMenu();
void OnBtnInsertGif2RE();
void OnBtnHideTest();
void OnBtnMsgBox(); void OnBtnWebkitGo();
void OnBtnWebkitBackward();
void OnBtnWebkitForeward();
void OnBtnWebkitRefresh(); //演示如何使用subscribeEvent来不使用事件映射表实现事件响应
bool OnListHeaderClick(EventArgs *pEvt); //UI控件的事件及响应函数映射表
EVENT_MAP_BEGIN()
EVENT_ID_COMMAND(, OnClose)
EVENT_ID_COMMAND(, OnMaximize)
EVENT_ID_COMMAND(, OnRestore)
EVENT_ID_COMMAND(, OnMinimize)
EVENT_NAME_CONTEXTMENU(L"edit_1140",OnEditMenu)
EVENT_NAME_COMMAND(L"btn_msgbox",OnBtnMsgBox)
EVENT_NAME_COMMAND(L"btnSelectGif",OnBtnSelectGIF)
EVENT_NAME_COMMAND(L"btn_menu",OnBtnMenu)
EVENT_NAME_COMMAND(L"btn_webkit_go",OnBtnWebkitGo)
EVENT_NAME_COMMAND(L"btn_webkit_back",OnBtnWebkitBackward)
EVENT_NAME_COMMAND(L"btn_webkit_fore",OnBtnWebkitForeward)
EVENT_NAME_COMMAND(L"btn_webkit_refresh",OnBtnWebkitRefresh)
EVENT_NAME_COMMAND(L"btn_hidetst",OnBtnHideTest)
EVENT_NAME_COMMAND(L"btn_insert_gif",OnBtnInsertGif2RE)
EVENT_MAP_END() //HOST消息及响应函数映射表
BEGIN_MSG_MAP_EX(CMainDlg)
MSG_WM_CREATE(OnCreate)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_DESTROY(OnDestory)
MSG_WM_CLOSE(OnClose)
MSG_WM_SIZE(OnSize)
MSG_WM_COMMAND(OnCommand)
MSG_WM_SHOWWINDOW(OnShowWindow)
CHAIN_MSG_MAP(SHostWnd)
REFLECT_NOTIFICATIONS_EX()
END_MSG_MAP() protected:
//////////////////////////////////////////////////////////////////////////
// 辅助函数
void InitListCtrl();
private:
BOOL m_bLayoutInited;/**<UI完成布局标志 */
};

maindlg.cpp

 // MainDlg.cpp : implementation of the CMainDlg class
//
///////////////////////////////////////////////////////////////////////////// #include "stdafx.h"
#include "MainDlg.h"
#include "helper/SMenu.h"
#include "../controls.extend/FileHelper.h" #include <dwmapi.h>
#pragma comment(lib,"dwmapi.lib") int CMainDlg::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
// MARGINS mar = {5,5,30,5};
// DwmExtendFrameIntoClientArea ( m_hWnd, &mar );//打开这里可以启用Aero效果
SetMsgHandled(FALSE);
return ;
} void CMainDlg::OnShowWindow( BOOL bShow, UINT nStatus )
{
if(bShow)
{
AnimateHostWindow(,AW_CENTER);
}
} struct student{
TCHAR szName[];
TCHAR szSex[];
int age;
int score;
}; //init listctrl
void CMainDlg::InitListCtrl()
{
SListCtrl *pList=FindChildByName2<SListCtrl>(L"lc_test");
if(pList)
{
SWindow *pHeader=pList->GetWindow(GSW_FIRSTCHILD);
pHeader->GetEventSet()->subscribeEvent(EVT_HEADER_CLICK,Subscriber(&CMainDlg::OnListHeaderClick,this)); TCHAR szSex[][]={_T("男"),_T("女"),_T("人妖")};
for(int i=;i<;i++)
{
student *pst=new student;
_stprintf(pst->szName,_T("学生_%d"),i+);
_tcscpy(pst->szSex,szSex[rand()%]);
pst->age=rand()%;
pst->score=rand()%+; int iItem=pList->InsertItem(i,pst->szName);
pList->SetItemData(iItem,(DWORD)pst);
pList->SetSubItemText(iItem,,pst->szSex);
TCHAR szBuf[];
_stprintf(szBuf,_T("%d"),pst->age);
pList->SetSubItemText(iItem,,szBuf);
_stprintf(szBuf,_T("%d"),pst->score);
pList->SetSubItemText(iItem,,szBuf);
}
}
} int funCmpare(void* pCtx,const void *p1,const void *p2)
{
int iCol=*(int*)pCtx; const DXLVITEM *plv1=(const DXLVITEM*)p1;
const DXLVITEM *plv2=(const DXLVITEM*)p2; const student *pst1=(const student *)plv1->dwData;
const student *pst2=(const student *)plv2->dwData; switch(iCol)
{
case ://name
return _tcscmp(pst1->szName,pst2->szName);
case ://sex
return _tcscmp(pst1->szSex,pst2->szSex);
case ://age
return pst1->age-pst2->age;
case ://score
return pst1->score-pst2->score;
default:
return ;
}
} bool CMainDlg::OnListHeaderClick(EventArgs *pEvtBase)
{
EventHeaderClick *pEvt =(EventHeaderClick*)pEvtBase;
SHeaderCtrl *pHeader=(SHeaderCtrl*)pEvt->sender;
SListCtrl *pList=FindChildByName2<SListCtrl>(L"lc_test"); SHDITEM hditem;
hditem.mask=SHDI_ORDER;
pHeader->GetItem(pEvt->iItem,&hditem);
pList->SortItems(funCmpare,&hditem.iOrder);
return true;
} void CMainDlg::OnDestory()
{
SListCtrl *pList=FindChildByName2<SListCtrl>(L"lc_test");
if(pList)
{
for(int i=;i<pList->GetItemCount();i++)
{
student *pst=(student*) pList->GetItemData(i);
delete pst;
}
}
SetMsgHandled(FALSE);
} LRESULT CMainDlg::OnInitDialog( HWND hWnd, LPARAM lParam )
{
m_bLayoutInited=TRUE;
InitListCtrl(); #ifdef DLL_SOUI
SWindow *pTst=FindChildByName(L"btn_tstevt");
if(pTst) SApplication::getSingleton().GetScriptModule()->subscribeEvent(pTst,EVT_CMD,"onEvtTstClick");
#endif return ;
} void CMainDlg::OnBtnWebkitGo()
{
SWkeWebkit *pWebkit= FindChildByName2<SWkeWebkit>(L"wke_test");
if(pWebkit)
{
SEdit *pEdit=FindChildByName2<SEdit>(L"edit_url");
SStringW strUrl=pEdit->GetWindowText();
pWebkit->SetAttribute(L"url",strUrl,FALSE);
}
} void CMainDlg::OnBtnWebkitBackward()
{
SWkeWebkit *pWebkit= FindChildByName2<SWkeWebkit>(L"wke_test");
if(pWebkit)
{
pWebkit->GetWebView()->goBack();
}
} void CMainDlg::OnBtnWebkitForeward()
{
SWkeWebkit *pWebkit= FindChildByName2<SWkeWebkit>(L"wke_test");
if(pWebkit)
{
pWebkit->GetWebView()->goForward();
}
} void CMainDlg::OnBtnWebkitRefresh()
{
SWkeWebkit *pWebkit= FindChildByName2<SWkeWebkit>(L"wke_test");
if(pWebkit)
{
pWebkit->GetWebView()->reload();
}
} void CMainDlg::OnBtnSelectGIF()
{
SGifPlayer *pGifPlayer = FindChildByName2<SGifPlayer>(L"giftest");
if(pGifPlayer)
{
CFileDialogEx openDlg(TRUE,_T("gif"),,,_T("gif files(*.gif)\0*.gif\0All files (*.*)\0*.*\0\0"));
if(openDlg.DoModal()==IDOK)
pGifPlayer->PlayGifFile(openDlg.m_szFileName);
}
} void CMainDlg::OnBtnMenu()
{
SMenu menu;
menu.LoadMenu(_T("menu_test"),_T("LAYOUT"));
POINT pt;
GetCursorPos(&pt);
menu.TrackPopupMenu(,pt.x,pt.y,m_hWnd);
} //演示如何响应菜单事件
void CMainDlg::OnCommand( UINT uNotifyCode, int nID, HWND wndCtl )
{
if(uNotifyCode==)
{
if(nID==)
{//nID==6对应menu_test定义的菜单的exit项。
PostMessage(WM_CLOSE);
}else if(nID==)
{//about SOUI
STabCtrl *pTabCtrl = FindChildByName2<STabCtrl>(L"tab_main");
if(pTabCtrl) pTabCtrl->SetCurSel(_T("about"));
}
}
} void CMainDlg::OnBtnHideTest()
{
SWindow * pBtn = FindChildByName(L"btn_hidetst");
if(pBtn) pBtn->SetVisible(FALSE,TRUE);
} #include "skinole\ImageOle.h" void CMainDlg::OnBtnInsertGif2RE()
{
SRichEdit *pEdit = FindChildByName2<SRichEdit>(L"re_gifhost");
if(pEdit)
{
ISkinObj * pSkin = GETSKIN(L"gif_penguin");
if(pSkin)
{
RichEdit_InsertSkin(pEdit,pSkin);
}
}
} void CMainDlg::OnBtnMsgBox()
{
SMessageBox(NULL,_T("this is a message box"),_T("haha"),MB_OK|MB_ICONEXCLAMATION);
SMessageBox(NULL,_T("this message box includes two buttons"),_T("haha"),MB_YESNO|MB_ICONQUESTION);
SMessageBox(NULL,_T("this message box includes three buttons"),NULL,MB_ABORTRETRYIGNORE);
}

maindlg.cpp的主要工作就是调用SHostWnd的FindChildByName/FindChildByID查找到SOUI的控件,然后调用控件提供的方法完成对控件的操作。

大家可能发现使用SOUI的这个main函数相对于其它程序可能要更加复杂,这是为了达到程序配置的灵活性需要付出的代价。

好在SOUI提供了应用程序向导,它会帮助你点两个按钮就生成一整套框架。

SOUI与其它应用程序开发框架

SOUI是一个使用纯Win32 SDK开发的UI库,内核部分使用了pugixml这个第三方库作为XML解析的模块,除此之外,不再依赖其它第三方库,同时所有使用的模块都可以通过源代码编译。

SOUI提供了一整套完整的UI开发框架,不需要依赖其它的如MFC,WTL等开发框架。同时由于SOUI是纯win32的SDK开发的,它理论上也可以和任意的其它开发框架共存。(实际处理中由于SOUI中使用的一些类的命名可能和其它框架冲突,因此可能需要注意命名空间的使用。)

第三篇:用SOUI能做什么?的更多相关文章

  1. 第二十五篇:在SOUI中做事件分发处理

    不同的SOUI控件可以产生不同的事件.SOUI系统中提供了两种事件处理方式:事件订阅 + 事件处理映射表(参见第八篇:SOUI中控件事件的响应) 事件订阅由于直接将事件及事件处理函数连接,不存在事件分 ...

  2. 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)

    从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://w ...

  3. &lpar;转&rpar; 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)

    原文地址: http://www.cnblogs.com/lyhabc/p/4682986.html 这一篇是从0开始搭建SQL Server AlwaysOn 的第三篇,这一篇才真正开始搭建Alwa ...

  4. 第三篇 Entity Framework Plus 之 Query Cache

    离上一篇博客,快一周,工作太忙,只能利用休息日来写一些跟大家分享,Entity Framework Plus 组件系列文章,之前已经写过两篇 第一篇 Entity Framework Plus 之 A ...

  5. 我的屌丝giser成长记-研三篇

    进入研三以来,基本都是自己的*时间了,从导师的项目抽离出来,慢慢的都交给师弟他们来负责.研三的核心任务就是找工作以及写毕业论文,因为有导师科研基金项目成果作为支撑,所以自己的论文没什么可担心,一切都 ...

  6. 深入理解javascript函数系列第三篇——属性和方法

    × 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...

  7. 第一篇:SOUI是什么?

    概述 用C++做产品最痛苦的是什么?肯定是做UI. SOUI的使命就是把痛苦的UI变化成快乐的UI. 什么?UI还能快乐?脑子进水了吗? 当你看完这个系统教程的时候相信你面对UI至少不会再痛苦.你可以 ...

  8. RabbitMQ学习总结 第三篇:工作队列Work Queue

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  9. 第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装

    微信服务器和第三方服务器之间究竟是通过什么方式进行对话的? 下面,我们先看下图: 其实我们可以简单的理解: (1)首先,用户向微信服务器发送消息: (2)微信服务器接收到用户的消息处理之后,通过开发者 ...

随机推荐

  1. &lbrack;LintCode&rsqb; Best Time to Buy and Sell Stock 买卖股票的最佳时间

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  2. pathinfo&lpar;&rpar;、dirname&lpar;&rpar;、basename&lpar;&rpar;获得文件的路径,名称等信息说明

    在PHP中,若想通过函数获得一个文件的路径.名称,或者是扩展名等,是非常容易的一件事.可以使用dirname().basename().pathinfo()等多种途径获得相应的信息. 假设现在有一个图 ...

  3. 关于phpcms中mysql和mysqli的区别

    用phpcms开发一个考试成绩查询的小模块,用电脑上以前下载的phpcms版本为框架开发,一切顺利.想着下载一个最新版本,以后也免了升级的麻烦.于是,下载好,然后把模块目录.model数据库连接文件. ...

  4. 【09&lowbar;242】Valid Anagram

    Valid Anagram My Submissions Question Total Accepted: 43694 Total Submissions: 111615 Difficulty: Ea ...

  5. CH round &num;55 Streaming &num;6

    T^T Saffah大神照样刷我这样诚心诚意想做一套NOIP模拟题的蒟蒻. 第一题 九九归一 好diao的名字... 题意就是给定一队$n,q$,求在模$n$意义下一个数$x$自乘的循环节长度. 当$ ...

  6. MD5加密算法

    package com.bao.tools.encryption; import java.security.MessageDigest;import java.security.NoSuchAlgo ...

  7. Delphi中编辑word

      其他(28)   //启动Word   try     wordapplication1.connect;   except     messagedlg('word may not be ins ...

  8. JPA--多对多关系

    JPA中,多对多关系用@ManyToMany标示. 关系维护端: package com.yl.demo1.bean.manyTomany; import java.util.HashSet; imp ...

  9. Java学习--Equals与&OpenCurlyDoubleQuote;&equals;&equals;”

    在Java规范中,它对equals()方法的使用必须要遵循如下几个规则: equals 方法在非空对象引用上实现相等关系: 1.自反性:对于任何非空引用值 x,x.equals(x) 都应返回 tru ...

  10. springboot中配置文件application&period;properties的理解

    前言 Spring Boot使用"习惯优于配置"(项目中存在大量的配置,此外还内置了一个习惯性的配置,让你无需手动进行配置)的理念让你的项目快速运行起来.所以,我们要想把Sprin ...