UNICODE:它是用兩個(gè)字節(jié)表示一個(gè)字符的方法。比如字符'A'在ASCII下面是一個(gè)字符,可'A'在UNICODE下面是兩個(gè)字符,高字符用0填充,而且漢字'程'在ASCII下面是兩個(gè)字節(jié),而在UNICODE下仍舊是兩個(gè)字節(jié)。UNICODE的用處就是定長表示世界文字,據(jù)統(tǒng)計(jì),用兩個(gè)字節(jié)可以編 現(xiàn)存的所有文字而沒有二義。
MBCS,它是多字節(jié)字符集,它是不定長表示世界文字的編 。MBCS表示英文字母時(shí)就和ASCII一 (這也是我們?nèi)菀装袽BCS和ASCII搞混的原 ),但表示其他文字時(shí)就需要用多字節(jié)。
WINDOWS下面的程序設(shè)計(jì)可以支持MBCS和UNICODE兩種編碼的字符串,具體用哪種就看定義了MBCS宏還是UNICODE宏。MBCS宏對(duì)應(yīng)的字符串指針是char*也就是LPSTR,UNICODE對(duì)應(yīng)的指針是unsigned short*也就是LPWSTR,為了寫程序方便微軟定義了類型LPTSTR,在MBCS下他就是char*,在UNICODE下它是unsigned char*,這 就可以重定義一個(gè)宏進(jìn)行不同字符集的轉(zhuǎn)換了。
LPTSTR、LPCSTR、LPCTSTR、LPSTR的意義:
LPSTR: 32bit指針指向一個(gè)字符串,每個(gè)字符占1字節(jié)
LPCSTR: 32-bit指針指向一個(gè)常字符串,每個(gè)字符占1字節(jié)
LPCTSTR: 32-bit指針指向一個(gè)常字符串,每字符可能占1字節(jié)或2字節(jié),取決于Unicode是否定義
LPTSTR: 32-bit指針每字符可能占1字節(jié)或2字節(jié),取決于Unicode是否定義
Windows使用兩種字符集ANSI和UNICODE,前者就是通常使用的單字節(jié)方式,但這種方式處理象中文這樣的雙字節(jié)字符不方便,容易出現(xiàn)半個(gè)漢字的情況。而后者是雙字節(jié)方式,方便處理雙字節(jié)字符。WindowsNT的所有與字符有關(guān)的函數(shù)都提供兩種方式的版本,而Windows9x只支持ANSI方式。_T一般同字常數(shù)相關(guān),如_T("Hello"。如果你編譯一個(gè)程序?yàn)锳NSI方式,_T實(shí)際不起任何作用。而如果編譯一個(gè)程序?yàn)閁NICODE方式,則編譯器會(huì)把"Hello"字符串以UNICODE方式保存。_T和_L的區(qū)別在于,_L不管你是以什么方式編譯,一律以UNICODE方式保存.
Windows核心編程的第一章。
L是表示字符串資源為Unicode的。
比如
wchar_t Str[] = L"Hello World!";
這個(gè)就是雙子節(jié)存儲(chǔ)字符了。
_T是一個(gè)適配的宏~
當(dāng)
#ifdef _UNICODE的時(shí)候
_T就是L
沒有#ifdef _UNICODE的時(shí)候
_T就是ANSI的。
比如
LPTSTR lpStr = new TCHAR[32];
TCHAR* szBuf = _T("Hello");
以上兩句使得無論是在UNICODE編譯條件下都是正確編譯的。
而且MS推薦你使用相匹配的字符串函數(shù)。
比如處理LPTSTR或者LPCTSTR 的時(shí)候,不要用strlen ,而是要用_tcslen
否則在UNICODE的編譯條件下,strlen不能處理 wchar_t*的字符串。
T是非常有意思的一個(gè)符號(hào)(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一種中間類型,既不明確表示使用 MBCS,也不明確表示使用 UNICODE。那到底使用哪種字符集?編譯的時(shí)候才決定
本文轉(zhuǎn)自:
http://littlecity.blog.163.com/blog/static/3577802620093895941438/
摘要: 最近有些人在問MFC編程一些要點(diǎn),有一些句柄的獲取、指針的獲取是常見的問題,本文將對(duì)這些問題做以解釋,參考了前人的筆錄(見reference),希望能夠幫助大家更方便地進(jìn)行MFC程序開發(fā)。
一般我們使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架,無論是多文檔還是單文檔,都存在指針和句柄獲取和操作...
閱讀全文
摘要: Node.js Manual & DocumentationTable Of Contents
Synopsis 概要Global Objects 全局對(duì)象
globalprocessrequire()require.resolve()require.paths__filename__dirnamemoduleTimers 定時(shí)器
setTimeout(callback, ...
閱讀全文
筆者現(xiàn)在了解一種比較簡單的方法,即:
修改CXXAPP中的InitInstance函數(shù),將原來的模態(tài)對(duì)話框改為非模態(tài)對(duì)話框,及修改
view plaincopy to clipboardprint?
INT_PTR nResponse = dlg.DoModal();
INT_PTR nResponse = dlg.DoModal();
為
view plaincopy to clipboardprint?
dlg.Create(CModalHideDlg::IDD); //創(chuàng)建為非模態(tài)對(duì)話框
dlg.ShowWindow(SW_HIDE); //創(chuàng)建完畢后,可以設(shè)置對(duì)話框的顯示方式,正常為“SW_SHOW”,
//在此,我們使用“SW_HIDE”將對(duì)話框隱藏,但是在進(jìn)程列表中仍然可以看到
dlg.RunModalLoop(); //消息循環(huán)
dlg.Create(CModalHideDlg::IDD); //創(chuàng)建為非模態(tài)對(duì)話框
dlg.ShowWindow(SW_HIDE); //創(chuàng)建完畢后,可以設(shè)置對(duì)話框的顯示方式,正常為“SW_SHOW”,
//在此,我們使用“SW_HIDE”將對(duì)話框隱藏,但是在進(jìn)程列表中仍然可以看到
dlg.RunModalLoop(); //消息循環(huán)
還有其他一些朋友的方法:
有很多應(yīng)用程序要求一起動(dòng)就隱藏起來,這些程序多作為后臺(tái)程序運(yùn)行,希望不影響其他窗口,
往往只在托盤區(qū)顯示一個(gè)圖標(biāo)。這些程序通常都是對(duì)話框程序,而對(duì)話框在初始化的過程上與SDI
、MDI的初始化是不同的,對(duì)話框只需要DoModule或者是CreateDialog等等對(duì)話框函數(shù)調(diào)用一次便
可,SDI、MDI則要好幾步才行。這樣看來,對(duì)話框在使用方法上面是隱藏了不少細(xì)節(jié)的,其中就
沒有SDI、MDI所要求的ShowWindow(nCmdShow)這一步。因此對(duì)話框要想一運(yùn)行就隱藏,并不是很
直接的。有一些方法可以做到這一點(diǎn),下面我們就來看看幾種方案。
1.定時(shí)器
最直觀,又是最無奈的一個(gè)方法就是使用定時(shí)器。既然我們?cè)趯?duì)話框開始顯示之前不能用ShowWin
dow(SW_HIDE)將其隱藏,那就給一個(gè)時(shí)間讓它顯示,完了我們?cè)陔[藏它。
方法:
1.在OnInitDialog()函數(shù)里設(shè)置定時(shí)器:(WINDOWS API里面響應(yīng)消息WM_INITDIALOG)
SetTimer(1, 1, NULL);
2.添加處理WM_TIMER的消息處理函數(shù)OnTimer,添加代碼:
if(nIDEvent == 1)
{
DeleteTimer(1);
ShowWindow(SW_HIDE);
}
這種方法的缺點(diǎn)是顯而易見的,使用定時(shí)器,使得程序的穩(wěn)定性似乎打一個(gè)折扣;窗口是要先顯
示出來的,那么效果就是窗口閃了一下消失。
2.改變對(duì)話框顯示狀況
在對(duì)話框初始化時(shí)改變其顯示屬性可以讓它隱藏起來。方法是調(diào)用SetWindowPlacement函數(shù):
BOOL CDialogExDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//DO something
WINDOWPLACEMENT wp;
wp.length=sizeof(WINDOWPLACEMENT);
wp.flags=WPF_RESTORETOMAXIMIZED;
wp.showCmd=SW_HIDE;
SetWindowPlacement(&wp);
return TRUE;
}
在需要顯示時(shí)(通常是響應(yīng)熱鍵或者托盤圖標(biāo)的鼠標(biāo)消息):
WINDOWPLACEMENT wp;
wp.length=sizeof(WINDOWPLACEMENT);
wp.flags=WPF_RESTORETOMAXIMIZED;
wp.showCmd=SW_SHOW;
SetWindowPlacement(&wp);
這樣的效果很不理想:窗口顯示在屏幕的左上角,并且是只有標(biāo)題欄,要正常顯示,還需加上如
下代碼:
定義一個(gè)成員變量CRect rect;
在OnInitDialog()里面:
GetWindowRect(&rect);
在需要顯示的地方:
SetWindowPos(&wndNoTopMost, wndRc.left, wndRc.top, wndRc.right, wndRc.bottom,
SWP_SHOWWINDOW);
CenterWindow();
即使這樣,效果還是很差。
這種方法還有一個(gè)弊端是當(dāng)程序開始運(yùn)行并且隱藏起來后,原來激活的窗口變成了非激活狀態(tài)了
,而當(dāng)對(duì)話框顯示出來后,對(duì)話框自身也是非激活狀態(tài)的。
3.不繪制窗口
當(dāng)對(duì)話框顯示時(shí)將要響應(yīng)消息WM_PAINT繪制客戶區(qū),相應(yīng)消息WM_NCPAINT繪制窗口邊框。我們?cè)?/span>
窗口第一次自繪自身時(shí)隱藏窗口,可以收到比較良好的效果。由于窗口是先畫窗口邊框,所以我
們僅需處理WM_NCPAINT即可。代碼如下:
添加WM_NCPAINT處理函數(shù)。
void CMyDialog::OnNcPaint()
{
static int i = 2;
if(i > 0)
{
i --;
ShowWindow(SW_HIDE);
}
else
CDialog::OnNcPaint();
}
這里有個(gè)問題:為什么要定義靜態(tài)變量i而且設(shè)其值為2呢?
我們只要窗口隱藏第一次,所以定義這個(gè)變量可以判斷是否時(shí)首次顯示窗口。當(dāng)程序開始運(yùn)行時(shí)
,系統(tǒng)發(fā)送(SendMessage)WM_NCPAINT消息,此時(shí)程序的窗口邊框應(yīng)該被顯示,但是此時(shí)我們沒
有作任何顯示的操作,而是將窗口隱藏,ShowWindow(SW_HIDE)將把窗口的WS_VISIBLE屬性去掉,
繼續(xù)執(zhí)行,程序?qū)z查WS_VISIBLE屬性,如果沒有則顯示窗口,所以又發(fā)送了一個(gè)WM_NCPAINT消
息。所以我們要處理兩次WM_NCPAINT消息。
在需要窗口顯示時(shí),調(diào)用ShowWindow(SW_SHOW)即可。
程序執(zhí)行的結(jié)果是,原來處于激活狀態(tài)的窗口可能會(huì)閃動(dòng)兩下,然后仍然處于激活狀態(tài)。這種處
理方式比上面的方式要優(yōu)越得多。
4.將對(duì)話框作為子窗口
這種方法是采用SDI框架,主窗口始終隱藏,對(duì)話框作為主窗口的成員變量,在CMainFrame::OnCr
eate()里面加入下代碼:
if(!dlg.Create(IDD_MYDIALOG, this))
{
return –1;
}
dlg.ShowWindow(SW_HIDE);
在要顯示對(duì)話框的地方用dlg.ShowWindow(SW_SHOW);即可。注意,主窗口一定要隱藏,否則對(duì)話
框可能會(huì)閃現(xiàn)一下。
隱藏狀態(tài)欄窗口
上面介紹了幾種檢查對(duì)話框的方法,大家如果試過的話可能已經(jīng)注意到系統(tǒng)狀態(tài)欄里在程序啟動(dòng)
時(shí)會(huì)有程序的圖標(biāo)閃過,在隱藏對(duì)話框的時(shí)候這個(gè)也是要隱藏的,方法很簡單:
在OnInitDialog()函數(shù)里面加上ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);即可。在
要顯示窗口的地方加上代碼ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);即將窗口的擴(kuò)
展樣式改回來。
以上是我的一點(diǎn)經(jīng)驗(yàn)總結(jié),有錯(cuò)誤或不完善的地方還望大家提出指正。歡迎大家與我聯(lián)系。
本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://www.shnenglu.com/humanchao
1、主程序
1 m_bStopMsg = TRUE;
2 HANDLE hPromptThread = StartPromptThread();
3 if (!hPromptThread)
4 {
5 LOG("啟動(dòng)導(dǎo)入數(shù)據(jù)提示框線程失敗");
6 }
7
8 while (m_bStopMsg)
9 {
10 MSG msg;
11 ::GetMessage( &msg, this->m_hWnd, NULL, NULL );
12 ::TranslateMessage( &msg );
13 ::DispatchMessage( &msg );
14 }
2、啟動(dòng)線程
1 HANDLE CBarView::StartPromptThread()
2 {
3 LOG("啟動(dòng)導(dǎo)入數(shù)據(jù)提示線程");
4 CWinThread* hThread = AfxBeginThread((AFX_THREADPROC)CBarView::RunPromptDialog,(LPVOID)this);
5
6 return (m_hPromptThread = hThread->m_hThread);
7 }
3、線程函數(shù)
1 DWORD WINAPI CBarView::RunPromptDialog(LPVOID Param)
2 {
3 CBarView* barObj = (CBarView*)Param;
4 barObj->waitObj = new CImportDataPromptDialog();
5 barObj->waitObj->Create(IDD_DIALOGPROMPT, NULL);
6
7 barObj->waitObj->ShowWindow(SW_SHOW);
8
9 barObj->m_bStopMsg = FALSE;
10 return 0;
11 }
4、結(jié)束線程函數(shù)
1 void CBarView::StopThread()
2 {
3 if (NULL != waitObj)
4 {
5 delete waitObj;
6 }
7
8 if (m_hPromptThread != NULL)
9 {
10 ::TerminateThread(m_hPromptThread, 0 );
11 m_hPromptThread = NULL;
12 LOG("結(jié)束導(dǎo)入數(shù)據(jù)提示線程");
13 }
14 }
以下轉(zhuǎn)自:
http://blog.csdn.net/hellothere/article/details/1788310
Windows多線程與對(duì)話框
Windows的對(duì)話框是獲取信息輸入的主要手段,增加線程則是獲得更好UI響應(yīng)的重要方式。由于Windows在處理對(duì)話框時(shí)進(jìn)行線程調(diào)度的特殊性,如果不對(duì)此加以特別注意,增加線程可能不能帶來UI響應(yīng)的改善。
1 跨線程創(chuàng)建對(duì)話框
1.1 需求
有這樣的應(yīng)用場景:創(chuàng)建非模態(tài)對(duì)話框后需要馬上做些耗時(shí)的工作,而同時(shí)又希望能夠立刻在對(duì)話框上操作,所以,希望讓非模態(tài)對(duì)話框工作在單獨(dú)的線程上。
1.2 方案
主線程啟動(dòng)一個(gè)UI線程,并且,讓這個(gè)線程創(chuàng)建非模態(tài)對(duì)話框。
想法是:既然用單獨(dú)的線程創(chuàng)建了對(duì)話框,所以,主線程在創(chuàng)建UI線程后,就可以繼續(xù)自己其他耗時(shí)的工作了。
1.3 實(shí)現(xiàn)
用一個(gè)簡單的例子程序來試驗(yàn)這個(gè)方案:在VC++中創(chuàng)建一個(gè)基于SDI的MFC應(yīng)用程序,在其CView派生類中處理“Call”菜單命令,創(chuàng)建派生自CWinThread的UI線程,在這個(gè)UI線程初始化過程中創(chuàng)建一個(gè)對(duì)話框。
1.3.1 單獨(dú)的UI線程創(chuàng)建對(duì)話框
實(shí)現(xiàn)一個(gè)派生自CWinThread的UI線程類,其中最關(guān)鍵的是CreateMyDlg和DestroyMyDlg函數(shù)。
類如下
class UIWorker : public CWinThread
{
DECLARE_DYNCREATE(UIWorker)
protected:
UIWorker(); // protected constructor used by dynamic creation
// Attributes
public:
// Operations
public:
bool CreateMyDlg( void );
void SetOwnerWnd( HWND hWnd );
void DestroyMyDlg( void );
……
private:
CDlgUserTest* m_pDlgTest;
HWND m_hOwnerWnd;
};
CreateMyDlg和DestroyMyDlg的實(shí)現(xiàn)都非常簡單
bool UIWorker::CreateMyDlg( void )
{
m_pDlgTest = new CDlgUserTest;
if ( NULL == m_pDlgTest )
{
return false;
}
CWnd* pWnd = NULL;
if ( NULL != m_hOwnerWnd )
{
pWnd = reinterpret_cast<CWnd*>( CWnd::FromHandle( m_hOwnerWnd ));
if ( NULL == pWnd )
{
return false;
}
}
BOOL bSuccess = m_pDlgTest->Create( IDD_DIALOG_TEST, pWnd );
if ( bSuccess )
{
bSuccess = m_pDlgTest->ShowWindow( SW_SHOW );
}
return bSuccess?true:false;
}
void UIWorker::DestroyMyDlg( void )
{
if ( NULL != m_pDlgTest )
{
delete m_pDlgTest;
m_pDlgTest = NULL;
}
}
1.3.2 主線程創(chuàng)建UI線程
主線程就更加簡單了。在菜單的對(duì)應(yīng)操作中,創(chuàng)建線程,為了表示主線程繼續(xù)工作,提供一個(gè)循環(huán)。
bool CUserView::Call(void)
{
m_pUIWorker = static_cast<UIWorker*>( AfxBeginThread(
RUNTIME_CLASS( UIWorker )));
for ( int i = 0; i < 100000; ++i )
for ( int j = 0; j < 10000; ++j )
;
return true;
}
1.4 結(jié)果:奇怪的延遲
希望達(dá)到的效果是:
主程序啟動(dòng)后,顯示一個(gè)單文檔視界面,有一個(gè)Work菜單
點(diǎn)擊Call菜單后,對(duì)話框應(yīng)該馬上彈出,顯示為:
執(zhí)行中,對(duì)話框不會(huì)馬上彈出,而會(huì)等待一定的時(shí)間,直到循環(huán)結(jié)束,CUserView的Call函數(shù)返回,對(duì)話框才會(huì)彈出。等待的時(shí)間和循環(huán)的長短成正比。
2 問題分析
2.1 不單純的對(duì)話框:要求Windows作特殊處理
對(duì)話框是一種很不單純的窗口。無論是創(chuàng)建、消息分發(fā)還是銷毀,Windows都會(huì)對(duì)對(duì)話框做一些特殊的處理。如果用SDK進(jìn)行對(duì)話框編程,就會(huì)發(fā)現(xiàn)創(chuàng)建對(duì)話框需要專門的Win32 API。而且,我們查閱平臺(tái)SDK的講述時(shí),也會(huì)發(fā)現(xiàn)對(duì)話框需要Windows進(jìn)行若干額外的“照顧”。事實(shí)上,之所以會(huì)出現(xiàn)前述的“延遲”情況,就是Windows進(jìn)行額外協(xié)調(diào)的結(jié)果。
2.2 窗口協(xié)調(diào)導(dǎo)致等待
2.2.1 Windows協(xié)調(diào)對(duì)話框彈出過程
使用SPY++研究窗口消息,會(huì)發(fā)現(xiàn)非模態(tài)對(duì)話框創(chuàng)建時(shí),原來擁有焦點(diǎn)的窗口會(huì)收到WM_KILLFOCUS消息,而且獲得焦點(diǎn)的窗口是創(chuàng)建的對(duì)話框。
2.2.2 線程需要分發(fā)消息,不能堵塞
根據(jù)例子來看,這個(gè)窗口焦點(diǎn)的協(xié)調(diào)過程被上升到了線程協(xié)調(diào)的層次。現(xiàn)象就是:如果被去激活的窗口的線程被阻塞,不能立刻處理WM_KILLFOCUS消息的話,創(chuàng)建對(duì)話框的線程也會(huì)被阻塞,對(duì)話框一直不能被顯示出來,直到線程不再阻塞,WM_KILLFOCUS被分發(fā)和處理。
2.3 解決方案
這個(gè)問題產(chǎn)生的原因是:在主線程繁忙的時(shí)候有主線程必須要處理的消息,也就是主線程消息循環(huán)因?yàn)榇翱谔幚砗瘮?shù)占用時(shí)間過長而被阻塞。因此,這個(gè)問題更多是一個(gè)設(shè)計(jì)問題而非技術(shù)難點(diǎn)。也許,我們?cè)搯柕氖牵?/span>
n 我真的要用一個(gè)冗長的工作來阻塞主線程這樣長的時(shí)間嗎?
n 我是否可以在單獨(dú)的一個(gè)工作者線程中來處理這個(gè)長的工作?
考慮了其他的可能性后,如果對(duì)上述問題的答案仍然為“是”的話,可以采取以下解決方案:因?yàn)槲覀內(nèi)鄙俚氖窍⒀h(huán),所以,加上消息循環(huán),讓對(duì)話框能夠顯示出來之后,再去進(jìn)行其他工作的處理。
bool CUserView::Call(void)
{
m_pUIWorker = static_cast<UIWorker*>( AfxBeginThread(
RUNTIME_CLASS( UIWorker )));
while ( !m_pUIWorker->GetDoneFlag())
{
MSG msg;
::GetMessage( &msg, this->m_hWnd, NULL, NULL );
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
for ( int i = 0; i < 100000; ++i )
for ( int j = 0; j < 10000; ++j )
;
return true;
}
紅色的代碼就是加上消息循環(huán)。要注意的是,相應(yīng)的線程類里面應(yīng)該在顯示出對(duì)話框后設(shè)置一個(gè)標(biāo)志,并且讓主線程可以查詢到這個(gè)標(biāo)志,從而終止這個(gè)臨時(shí)的消息循環(huán)。
3 啟示
3.1 Windows線程調(diào)度
Windows的線程調(diào)度原則對(duì)于程序員來說非常簡單。這條原則是:程序員無法決定線程調(diào)度過程。
只是因?yàn)?#8220;程序員無法決定線程調(diào)度過程”,并不意味著程序員不應(yīng)該去了解一些特別的線程調(diào)度過程。在某些場合下,正如上面在和對(duì)話框相關(guān)的某些時(shí)機(jī),也許,Windows的線程調(diào)度是有明確規(guī)則的。所以,大多數(shù)情況下,程序員可以認(rèn)為Windows的線程調(diào)度對(duì)于自己來說是一個(gè)黑盒。但是,某些時(shí)候,這個(gè)盒子中間發(fā)生的事情也需要了解和掌握。
3.2 對(duì)話框
對(duì)話框是一個(gè)古老的話題,很多的人仔細(xì)討論了對(duì)話框的方方面面。對(duì)話框一直是Windows里面非常特殊的一種窗口。它的消息循環(huán),與其他窗口的協(xié)調(diào)要求,都和普通的窗口有不同之處。因此,為了配合這些不同之處,Windows在線程協(xié)調(diào)上也做了一些手腳。
3.3 多線程編程更多是一種設(shè)計(jì)
更重要的啟示是:多線程需要更多的考慮設(shè)計(jì)。
毫無疑問,多線程可以使多種工作并行進(jìn)行,提高工作效率,改善界面響應(yīng)。然而,多線程應(yīng)用中一個(gè)麻煩的問題是:決定對(duì)哪些工作使用單獨(dú)的線程。這個(gè)決定過程其實(shí)就是設(shè)計(jì)過程。如果設(shè)計(jì)方案不合理,比如,如本例子中反映出來的問題——在主線程被長時(shí)間的工作阻塞的情況下,增加的線程并不會(huì)給我們帶來明顯的響應(yīng)改善。而且,如果設(shè)計(jì)方案不合理,會(huì)帶來更多的“臨時(shí)機(jī)制”的采用,如本例中必須增加一個(gè)單獨(dú)的消息循環(huán),并且需要在兩個(gè)線程中就對(duì)話框是否創(chuàng)建出來進(jìn)行通訊。這樣的實(shí)現(xiàn)在很大程度上削減了希望用多線程帶來的好處。
SQLite查詢空值
1、當(dāng)插入數(shù)據(jù)位空時(shí)(如:Second= “”),數(shù)據(jù)中顯示內(nèi)容為(null)。如圖所示。

查詢顯示為空的列表:
1 select * from Test where Second is null
顯示結(jié)果:

查詢顯示不為空的列表:
1 select * from Test where Second not null
2、當(dāng)插入數(shù)據(jù)的字段不存在時(shí),數(shù)據(jù)庫中顯示為空。如圖所示。

查詢顯示為空的列表:
1 select * from Test where Second is ''
顯示結(jié)果

查詢顯示不為空的列表:
1 select * from Test where Second <> ''
摘要: SQLite庫可以解析大部分標(biāo)準(zhǔn)SQL語言。但它也省去了一些特性并且加入了一些自己的新特性。這篇文檔就是試圖描述那些SQLite支持/不支持的SQL語法的。查看關(guān)鍵字列表。
如下語法表格中,純文本用藍(lán)色粗體顯示。非終極符號(hào)為斜體紅色。作為語法一部分的運(yùn)算符用黑色Roman字體表示。
這篇文檔只是對(duì)SQLite實(shí)現(xiàn)的SQL語法的綜述,有所忽略。想要得到更詳細(xì)的信息,參考源代碼和語法文件̶...
閱讀全文
為了在Ubuntu下安裝那令人悲催的GCC,小弟可是絞盡腦汁,連干三天。。。當(dāng)我搞清楚那些破軟件m4,gmp mpfr,mpc等之間的依賴關(guān)系,依照強(qiáng)大的度娘提示下,安裝了一遍又一邊一邊又一邊·····它就是不成!shit!就當(dāng)俺不得不做出拋棄GCC的念頭之時(shí),又是度娘! <!--[if !vml]-->
<!--[endif]--> 原來Ubuntu11.04自帶GCC的!!! 在此建議各位大蝦,在安裝GCC之前,先check一下你的Linux中是否自帶了GCC。 <!--[if !vml]-->

<!--[endif]-->
下面是小弟,在這悲催的三天所學(xué)到如何在Ubuntu下安裝GCC的過程:
安裝過程
第一步,從網(wǎng)站http://gcc.gnu.org 上下載文件gcc-4.6.0.tar.bz2
第二步,將該文件拖至tmp目錄下。然后解壓縮,在命令行tar vxjf gcc-4.1.1.tar.bz2,
解壓后你可以看到在tmp目錄下有gcc-4.6.0文件

第三步,對(duì)源文件進(jìn)行配置,用命令
mkdir gcc-build
cd gcc-build
../gcc-4.6.0/configure --prefix=/usr/local/gcc-4.6.0 --enable-threads=posix --disable-checking --disable-multilib --enable-languages=c,c++
編譯錯(cuò)誤提醒:

<!--[if !vml]--><!--[endif]-->
提醒信息:configure: error: Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0+.
說明要安裝gcc需要GMP、MPFR、MPC這三個(gè)庫,于是又從網(wǎng)上下了三個(gè)庫的壓縮包。由于MPFR依賴GMP,而MPC依賴GMP和MPFR,所以要先安裝GMP,其次MPFR,最后才是MPC。這里三個(gè)庫我用的版本分別是gmp5.0.1,mpfr2.4.2和mpc0.8.1。
先開始安裝GMP。解壓GMP的壓縮包后,得到源代碼目錄gmp-5.0.1。在該目錄的同級(jí)目錄下建立一個(gè)臨時(shí)的編譯目錄,這里命名為gmp-build。然后開始配置安裝選項(xiàng),進(jìn)入gmp-build目錄,輸入以下命令進(jìn)行配置:
../gmp-5.0.1/configure --prefix=/usr/local/gmp-5.0.1
這里--prefix選項(xiàng)代表要將該庫安裝在哪里,我是裝在/usr/local/gmp-5.0.1目錄下,后面的安裝都會(huì)用到這個(gè)選項(xiàng)。不過這里又出現(xiàn)問題了,系統(tǒng)提示缺少m4: gmp configure: error: No usable m4 in $PATH or /usr/5bin。m4是一個(gè)宏處理器。
在網(wǎng)上查了一下這個(gè)問題的解決辦法,輸入以下命令進(jìn)行安裝:
sudo aptitude install build-essential m4
或在系統(tǒng)自帶的軟件中心尋m4

<!--[if !vml]--><!--[endif]-->
再經(jīng)歷這一切之后在度娘的幫助下,終于明白其實(shí)正確的安裝過程如下:
linux下軟件的“安裝”一般是需要3個(gè)步驟:
即configure,make和make install這三個(gè)命令編譯,而安裝的任何一個(gè)命令有疑問或者想查看命令相關(guān)的參數(shù),都可以在命令后加” --help”參數(shù)來查看安裝命令需要的參數(shù)。
其次需要說明的是,由于可能存在任何可能的情況,configure,make和make install這三個(gè)命令都有可能報(bào)錯(cuò),如果出錯(cuò),終端會(huì)給出錯(cuò)誤的信息,也就是error的提示,你需要針對(duì)錯(cuò)誤的類型去解決安裝中存在的問題,有問題的話可以在baidu或者google上搜搜出錯(cuò)信息看看,應(yīng)該有你要的答案,但是建議在google上搜。Linux是開源的,全世界的客戶多不勝數(shù)。遇到和你同樣的問題的人一定存在。所以,有什么error有什么問題,盡管找度娘,股溝。上面的資料十分的多。也可以到相關(guān)的Ubuntu論壇上去找,例如:http://forum.ubuntu.org.cn/index.php?sid=c9ccb2d7adcf8fdb78ac99d75581a332 好了,繼續(xù)話題。。。。。
1,安裝GCC需要四個(gè)相關(guān)的軟件:
m4(即an implementation of the traditional Unix macro processor)、
gmp(即GNU Multiple Precision Arithmetic Library)、
mpfr(即multiple-precision floating-point computations with correct rounding)
mpc(即C library for the arithmetic of complex numbers with arbitrarily high precision and correct rounding
下載3個(gè)軟件包及安裝參考http://www.comdyn.cn/from-web/68-server-setup/164-centos-48-gcc450.html
他們的依賴關(guān)系如右圖-----------
按照從內(nèi)圈到外圈的順序安裝(gmp的安裝需要m4,而mpfr依賴gmp,而mpc依賴gmp和mpfr,所以要先安裝m4,其次裝gmp,再其次mpfr,最后是mpc)
我安裝的后三個(gè)庫的版本分別是 <!--[if !vml]--><!--[endif]-->

<!--[if !supportLists]-->(I) <!--[endif]-->m4的安裝,首先需要說明的是,如果不安裝m4,在安裝gmp的時(shí)候系統(tǒng)會(huì)提示“m4: gmp configure: error: No usable m4 in $PATH or /usr/5bin”的錯(cuò)誤。因此首先需要安裝m4,命令如下
tar –zxvf m4.tar.gz 先解壓縮,然后進(jìn)入到m4目錄
./configure CC=”cc”
make
make install
由于沒有指定安裝目錄,因此安裝好后,可以查看默認(rèn)的/usr/local/bin目錄下,有一個(gè)m4的可執(zhí)行文件,網(wǎng)上資料說這是一個(gè)宏處理器。
<!--[if !supportLists]-->(II) <!--[endif]-->gmp的安裝,后面的安裝都是裝到了指定目錄下,所以我都是用root超級(jí)用戶操作的,用su命令切換到超級(jí)用戶。由于我是將gmp,mpfr和mpc分別安裝到了/usr/local/gmp432,/usr/local/mpfr242和/usr/local/mpc082目錄下,因此需要先進(jìn)入/usr/local/目錄下,以超級(jí)用戶運(yùn)行
mkdir gmp432 mkdir是創(chuàng)建目錄命令,即先創(chuàng)建安裝目錄,你也可以在任意目錄下建
mkdir mpfr242
mkdir mpc081
完成以后,進(jìn)入到gmp-4.3.2.tar.gz所在的目錄下,開始安裝gmp,
tar –vxzf gmp-4.3.2.tar.bz2 再壓縮,然后進(jìn)入到gmp-4.3.2目錄
cd gmp-4.3.2 (不知道怎么安裝的可以看一下解壓縮后該目錄下的INSTALL文件)
./configure --prefix=/usr/local/gmp432
make
make check
make install
安裝好后,可以查看/usr/local/gmp432目錄下有三個(gè)文件夾
<!--[if !supportLists]-->(III) <!--[endif]-->mpfr的安裝,
tar –vxzf mpfr-2.4.2.tar.bz2 先解壓縮,然后進(jìn)入到mpfr-2.4.2目錄
cd mpfr-2.4.2
./configure --prefix=/usr/local/mpfr432 --with-gmp=/usr/local/gmp432
make
make check
make install
mpc的安裝,(仍然在超級(jí)用戶下操作),同樣,不知道怎么安裝的可以看一下解壓縮后的INSTALL文件,
tar –zxvf mpc-0.8.1.tar.gz 先解壓縮,然后進(jìn)入到mpc-0.8.2目錄
cd mpc-0.8.1
./configure --prefix=/usr/local/mpc-0.8.1 --with-gmp=/usr/local/gmp432 --with-mpfr=/usr/local/mpfr242
make
make check
make install
安裝好這三個(gè)庫之后,就可以正式開始安裝gcc了。
與此前一樣,在gcc解壓后的文件夾的同級(jí)目錄下,建一個(gè)編譯gcc的臨時(shí)目錄:gcc-build。
mkdir gcc-build
cd gcc-build
<!--[if !vml]--><!--[endif]-->

進(jìn)入該目錄后配置安裝選項(xiàng):
../gcc-4.6.0/configure --prefix=/usr/local/gcc-4.6.0 --enable-threads=posix --disable-checking --disable-multilib --enable-languages=c,c++
--with-gmp=/usr/local/gmp-5.0.1 --with-mpfr=/usr/local/mpfr-2.4.2 --with-mpc=/usr/local/mpc-0.8.1
gcc的配置選項(xiàng)有很多,具體可以參考gcc源文件目錄下的安裝說明。這里只安裝了c和c++的編譯器。然后開始make編譯。本來以為就可以大功告成了,結(jié)果在編譯途中又出現(xiàn)了錯(cuò)誤:error while loading shared libraries: libmpc.so.2: cannot open shared object file: No such file or directory
在網(wǎng)上找到了解決方法,需要添加環(huán)境變量LD_LIBRARY_PATH以指出前面三個(gè)庫的位置,鍵入以下命令:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/mpc-0.8.1/lib:/usr/local/gmp-5.0.1/lib:/usr/local/mpfr-2.4.2/lib
然后運(yùn)行
make
然后就耐心等待。。。。。。。。。
在經(jīng)過漫長的2小時(shí)等待后,終于編譯完成。在安裝說明里面還有測試這一步,不過那是可選的,我也沒耐心去測試了。直接make install安裝,至此gcc就全部安裝完成了。不過目前還不能使用新版本的gcc,因?yàn)樾掳娴目蓤?zhí)行文件還沒加到命令的搜索路徑中。在這里我為新版的gcc和g++命令分別建立了一個(gè)軟鏈接。進(jìn)入/usr/bin目錄后,鍵入如下命令建立軟鏈接。
sudo ln -s /usr/local/gcc-4.5.0/bin/gcc gcc45
sudo ln -s /usr/local/gcc-4.5.0/bin/g++ g++45
這樣我使用新版本gcc的時(shí)候就可以用gcc45和g++45命令,同時(shí)也可使用原來的gcc編譯程序。當(dāng)然這里也可以直接將/usr/bin目錄下gcc,g++命令重新鏈接到新版本的gcc可執(zhí)行文件。在正式使用之前還有最后一個(gè)工作要做,就是將前面安裝的三個(gè)庫的路徑加進(jìn)環(huán)境變量LD_LIBRARY_PATH中,不然在編譯程序的時(shí)候會(huì)出錯(cuò)。由于我不想每次編譯程序都生成環(huán)境變量,所以需要編輯/etc目錄下的bash.bashrc文件配置shell環(huán)境。在這個(gè)文件中添加以下語句:
LD_LIBRARY_PATH=:/usr/local/mpc-0.8.1/lib:/usr/local/gmp-5.0.1/lib:/usr/local/mpfr-2.4.2/lib:/usr/local/gcc-4.5.0/lib
export LD_LIBRARY_PATH
保存重啟系統(tǒng)后,就可以使用新裝的gcc了。
需要說明的是,gcc的配置選項(xiàng)有很多,具體可以參考gcc源文件目錄下的安裝說明。這里只安裝了c和c++的編譯器。然后開始make編譯。
在正式使用之前還有最后一個(gè)工作要做,就是將前面安裝的三個(gè)庫的路徑加進(jìn)環(huán)境變量LD_LIBRARY_PATH中,不然在編譯程序的時(shí)候會(huì)出錯(cuò)。由于我不想每次編譯程序都生成環(huán)境變量,所以需要編輯/etc目錄下的bash.bashrc文件配置shell環(huán)境。在這個(gè)文件中添加以下語句:
LD_LIBRARY_PATH=:/usr/local/mpc-0.8.1/lib:/usr/local/gmp-5.0.1/lib:/usr/local/mpfr-2.4.2/lib:/usr/local/gcc-4.5.0/lib
export LD_LIBRARY_PATH
保存重啟系統(tǒng)后,就可以使用新裝的gcc了。
需要說明的是,如果make出錯(cuò),需要重新configure的話,先運(yùn)行一下make distclean來清除make的信息,再重新configure。
解壓縮*.tar.gz的命令是tar –zxvf *.tar.gz
解壓縮*.tar.bz2的命令是tar -jxvf *.tar.bz2
安裝完成好以后可以用 which gcc查看是否安裝好,命令運(yùn)行后終端顯示出安裝gcc的路徑。
<!--[if !vml]--><!--[endif]-->

打完,收工·······
本文轉(zhuǎn)自:http://ohyeahbbs.blog.51cto.com/1775490/568462
獲取本機(jī)IP地址
1 CString sLoginUser;
2 CString sLocalIP;
3 WORD wVersionRequested;
4 WSADATA wsaData;
5 wVersionRequested = MAKEWORD( 2, 0 );
6
7 if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
8 {
9 sLoginUser.TrimLeft();
10 sLoginUser.TrimRight();
11 sLocalIP = CCommonFun::ConvertHostNameToIP(sLoginUser);
12
13 WSACleanup( );
14 }
在CCommonFun類中:
1 CString CCommonFun::ConvertHostNameToIP( const CString &sHostName )
2 {
3 CString sIP;
4
5 HOSTENT *host_entry = gethostbyname(sHostName);
6 if( host_entry != 0 )
7 {
8 sIP.Format("%d.%d.%d.%d",
9 (host_entry->h_addr_list[0][0]&0x00ff),
10 (host_entry->h_addr_list[0][1]&0x00ff),
11 (host_entry->h_addr_list[0][2]&0x00ff),
12 (host_entry->h_addr_list[0][3]&0x00ff));
13 }
14
15 return sIP;
16 }
直接獲取:
1 #include "winsock.h"
2
3 WORD wVersionRequested;
4 WSADATA wsaData;
5 char name[255];
6 CString ip;
7 PHOSTENT hostinfo;
8 wVersionRequested = MAKEWORD( 2, 0 );
9
10 if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
11 {
12 if( gethostname ( name, sizeof(name)) == 0)
13 {
14 if((hostinfo = gethostbyname(name)) != NULL)
15 {
16 ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
17 }
18 }
19
20 WSACleanup( );
21 }
什么樣的程序員稱得上優(yōu)秀,根據(jù)我所看到,有如下體會(huì):
1、不愿意將就的人
程序設(shè)計(jì)工作是一項(xiàng)地地道道的腦力勞動(dòng),把工作做得很好和做的很差往往只在工作中的一個(gè)小小的細(xì)節(jié),我發(fā)現(xiàn)我身邊優(yōu)秀的程序員都不太喜歡將就,始終把自己的計(jì)算機(jī)和自己的開發(fā)環(huán)境調(diào)整到最佳狀態(tài),原來帶我的老員工甚至?xí)约簩懸恍┬」ぞ撸瑏硖岣吖ぷ餍省?/span>
2、不喜歡蠻干
腦力勞動(dòng)與體力勞動(dòng)不同,很多時(shí)候很難通過簡單的量的積累達(dá)到目的,尤其是處理一些難題的時(shí)候。一味的強(qiáng)調(diào)蠻干,加班幾乎天生與高手無緣。沒有思路的時(shí)候,換個(gè)環(huán)境,也許答案就在明天上班的路上想起。
3、愿意思考、專注改進(jìn)
程序員與其他勞動(dòng)者相似,熟練了以后都會(huì)形成慣性思維,會(huì)不自覺的用自己習(xí)慣的方式解決問題,但問題的形式與本質(zhì)總會(huì)變化,只有不斷的改進(jìn)才能使工作效率不斷提高。而把腦力勞動(dòng)變成體力勞動(dòng)的現(xiàn)象在實(shí)際工作中比比皆是。
4、良好的基礎(chǔ)和不斷的學(xué)習(xí)
良好的基礎(chǔ)與不斷的學(xué)習(xí)是天生的一對(duì)孿生兄弟,因?yàn)榛A(chǔ)好所以學(xué)的快,因?yàn)閷W(xué)得快,所以基本功好。良好學(xué)習(xí)習(xí)慣不是不停的簡單追蹤新技術(shù),一方面是了解新技術(shù),另一方面需要不斷的彌補(bǔ)思維盲區(qū),學(xué)習(xí)可以有很多種狀態(tài),有一種是聞一而知一,技也,有一種是聞一而知三,術(shù)也,有一種是聞一而知十,道也。
5、直接切入問題的能力
在解決一個(gè)問題的時(shí)候,有些人總是能夠直接切入問題核心,而有些人總是喜歡關(guān)注邊緣問題。直入主題是一種核心能力,需要思考,實(shí)踐,改進(jìn),積累,提高,周而復(fù)使,螺旋上升。另外我覺得這與思維方式與知識(shí)面關(guān)系很大,多涉獵一些領(lǐng)域沒有壞處。
***英語***:呵呵,對(duì),還是英語,流利的聽說讀寫。
本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://www.shnenglu.com/humanchao