工作中总结的编程小技巧
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工作中总结的编程小技巧相关的知识,希望对你有一定的参考价值。
技巧一: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
以上是关于工作中总结的编程小技巧的主要内容,如果未能解决你的问题,请参考以下文章