1. 程式人生 > >工作中總結的編程小技巧

工作中總結的編程小技巧

細節 wpa 例子 wchar 覆蓋 dst edit class a const

技巧一:int-->bool要註意的!
bool a=255;
bool b= 254;
理論上應該認為a==b,但是根據編譯器的不同,結果可能完全不一樣
所以更好的寫法是
char ch =1; 或者0
bool a = (0 != atoi(ch));

技巧二:將std::string轉int,double
先利用c_str()轉成C string,再用atoi()與atof()

技巧三:const_cast操作符可以強置去除const指針的const屬性

技巧四:CString讀取文本的每一行
CStdioFile LogIDFile;
char* pFileName = "Log.txt ";
CString strtemp;
if( LogIDFile.Open( pFileName, CFile::modeRead ))
{
LogIDFile.SeekToBegin();
LogIDFile.ReadString(strtemp);
}
LogIDFile.Close();

技巧五:win32下給任何一個句柄添加消息處理函數:
為了簡單假如在About對話框裏貼了一個 IDC_STATIC_1。在IDC_STATIC_1上掛了一個 IDB_BITMAP1。
IDC_STATIC_1 控件屬性,“通知”=Notify設為TRUE。
有了上面的假設後,就可以用下面的程序控制picture的全部行為。

LONG OldPicProc;
LRESULT CALLBACK PicProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_RBUTTONDOWN:
{
WORD xPos = LOWORD(lParam);
WORD yPos = HIWORD(lParam);
}
break;
}
return CallWindowProc((WNDPROC)OldPicProc, hWnd, message, wParam, lParam);
}


LRESULT CALLBACK About( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_INITDIALOG:
{
HWND hWnd = GetDlgItem(hDlg, IDC_STATIC_1);
OldPicProc = SetWindowLong(hWnd, GWL_WNDPROC, (LONG)PicProc);
}

return TRUE;

case WM_COMMAND:
if( LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL )
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}

技巧六:屏幕坐標轉三維坐標(反變換的過程)
void GetOGLPos(int x, int y, double * posX, double * posY, double * posZ)
{
GLint viewport[4];
GLdouble projection[16];
GLfloat winX, winY, winZ;

glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );

winX = (float)x;
winY = (float)viewport[3] - (float)y;
glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

gluUnProject( winX, winY, winZ, modelview, projection, viewport, posX, posY, posZ);
}

技巧七 寬字符字符串轉多字節字符串
//===方法1
TCHAR tcScriptName[MAX_PATH];
tcScriptName = "filename";
size_t i;
char tmp[MAX_PATH];
mbstate_t mbstate;

// Reset to initial shift state
::memset((void*)&mbstate, 0, sizeof(mbstate));

const wchar_t* wt = tcScriptName;
wcsrtombs_s(&i, tmp, MAX_PATH, &wt, MAX_PATH,&mbstate);
//===方法2
char * input = null;
wchar_t wc_input[MAX_USERNAME_LEN] = L"test";

int nLen = WideCharToMultiByte( CP_ACP, 0, wc_input, -1, NULL, 0, NULL, NULL );
int i = wcslen(wc_input)*sizeof(wchar_t);
input = (char*)realloc(input,i+1);
if (!input)
{
free(input);
input = (char*)malloc(i + 1);
}
WideCharToMultiByte( CP_ACP, 0, wc_input, -1, input, nLen, NULL, NULL );

//===方法3

采用USER_CONVERTION宏。A2T與T2A兩個宏在USER_CONVERTION作用域範圍內可以起到方便轉換的作用。

技巧八 獲得界面上所有控件
CWnd *pWnd = this->GetWindow( GW_CHILD );
while( pWnd )
{
if( pWnd->IsKindOf( RUNTIME_CLASS(CEdit) ) )
pWnd->ShowWindow(SW_SHOW);
pWnd = pWnd->GetWindow( GW_HWNDNEXT );
}

技巧九 判斷基類指針指向的派生類類型

方法一:
class A
{
public:
virtual int get_type_id()
{
return 0;
}
};

class B: public A
{
public:
int get_type_id()
{
return 1;
}
};

方法二:
用RTTI
class A
{
public:
virtual ~A(){} //必須

};

class B: public A
{
};

int main()
{
A * p = new B;
bool p_is_B = (typeid(B) == typeid(*p));
std::cout<<p_is_B<<std::endl;

p_is_B = (dynamic_cast<B*>(p) != 0);
std::cout<<p_is_B<<std::endl;
}

技巧十 窗口ID,句柄,指針三者相互轉換函數
ID--HANDLE--HWND三者之間的互相轉換
===============
id->句柄
hWnd = ::GetDlgItem(hParentWnd,id);
===============
id->指針
CWnd::GetDlgItem();
===============
句柄->id
id = GetWindowLong(hWnd,GWL_ID);
===============
句柄->指針
CWnd *pWnd=CWnd::FromHandle(hWnd);
===============
指針->ID
id = GetWindowLong(pWnd->GetSafeHwnd,GWL_ID);
=================
指針->句柄
hWnd=cWnd.GetSafeHandle() or mywnd->m_hWnd;

技巧十一 Debug調試正常,release下出錯的原因

debug下正常,release下不正常的原因大多在於變量未初始化及其引起的在調試模式下數組下標越界不報錯的問題。這種情況在release下將可能產生隨機性BUG,並且由於在release狀態下不易調試。可以在數值異常處設置調試輸出到文件或調試窗口(可采用ouputdebugstring()函數),並向程序流程上遊查詢出錯的源頭。故應養成定期編譯release版本的習慣。
下面的程序在debug中運行的很好。
thing * search(thing * something)
BOOL found;
for(int i = 0; i < whatever.GetSize(); i++)
{
if(whatever[i]->field == something->field)
{ /* found it */
found = TRUE;
break;
} /* found it */
}
if(found)
return whatever[i];
else
return NULL;
而在release中卻不行,因為debug中會自動給變量初始化found=FALSE,而在release版中則不會。所以盡可能的給變量、類或結構初始化。

技巧十二 在多文檔中繪制OpenGL圖形的主要步驟:
(1)、由於在多文檔中有多個窗口需要繪制,而當前的OpenGL渲染描述表只有一個,因此,在窗口的圖形繪制完之後,必須將OpenGL繪制描述表釋放,以備其他窗口使用。
(2)、必須新建一個視圖類,在該視圖類中對Windows設備描述表和OpengL的渲染描述表進行管理,而應用程序中的其他各視圖均從該類中派生。
(3)、在該新建的視圖類中定義一個OpenGL繪圖的虛函數,在其派生的類中可以對其進行重載,可以在應用程序中的視圖類直接調用OpenGL命令繪圖。
(4)、必須取消派生的視圖類的WM_DRAW消息處理函數和PreCretaeWindow函數。

技巧十三 MFC多文檔實現標簽頁切換各個視圖的方法(提供思路,細節不闡述)

1、首先創建一個child類型的對話框,在其上放置TAB control

2、在視圖類的初始化事件中將視圖指針與TAB control上的標簽綁定

3、設計TAB control的OnSelchange消息響應,用MDIActivate函數控制激活選中的標簽綁定的視圖

參見以下例子:http://www.vckbase.com/document/viewdoc/?id=838

技巧十三 OPENGL出現Z-Fighting的解決方法

1、繪制其中一個物體時禁用深度測試(若出現深度覆蓋錯誤的情況可以調整繪制順序)

2、采用glPolygonOffset函數將其中一個物體的位置做輕微位移

轉自:http://blog.csdn.net/gissirclyx/article/details/4744325

工作中總結的編程小技巧