T: | 昨天去面试,一个图行算法,难死我了! |
Q: | 昨天被通知面试上机复试!抽到一个图形算法的题,难死我了,没搞定!也让你们享用一下吧! 一个1600*800的图形(单色的),其信息存放在一个char phto[800][200]的数组,每个phto[200]中要存放1600个像素的信息,有像素的位置1,无像素的位置0。其中phto[800][200]中存放的是十六进制的数! 要求编写一个算法,随便画个什么波形(正弦,余弦等),最后把图形信息存放在数组 phto[800][200]中,并反回。 md ,我编了一个上午,把算法接到他们的测试程序上就是不出图,对位操作总是有点有适应! 那公司开价2K,不问学历,不看证件,编出算法的就OK,给2K。 看来我的水平不够2K,各位老大进来看一看,有能力拿2K的请出手,把你们的算法给小弟一观! (我把问题描述清楚了没有?)不甘心啊!再找不到工作,明天就把高程证给烧烧掉! |
A: | #include "math.h" char g_map[800][200]; #define PI 3.141592653589793 // void DrawLine(int x1,int y1,int x2,int y2); void MyLine(int x1,int y1,int x2,int y2) { int i=0; double d=((double)(y2-y1))/(x2-x1); for(i=x1;i<x2;i++) { DrawLine(i,(int)((i-x1)*d+y1+0.5),i,int((i-x1)*d+y1+d/2+0.5)); DrawLine(i+1,int((i-x1)*d+y1+d/2+0.5),i+1,int((i-x1)*d+y1+d+0.5)); } } void DrawPixel(int x,int y) { int a=x/8; int b=x%8; int c=1<<b; char *p=&g_map[y][a]; (*p)=(*p)|c; return; } void DrawLine(int x1,int y1,int x2,int y2) { int i=0; if(x1<x2) { MyLine(x1,y1,x2,y2); }else if(x1>x2) { MyLine(x2,y2,x1,y1); }else { if(y2<y1) { i=y2; y2=y1; y1=i; } for(i=y1;i<=y2;i++) DrawPixel(x1,i); } } void DrawSin() { double dAng=0,dAng1; int iY=0,iY1=0; for(int i=0;i<360;i++) { dAng=i/PI; dAng1=(i+1)/PI; iY=int(sin(dAng)*20+20); iY1=int(sin(dAng1)*20+20); DrawLine(i,iY,i+1,iY1); } return; } int GetPix(int x,int y) { int ret=0; int a=x/8; int b=x%8; int c=1<<b; char *p=&g_map[y][a]; if(((*p)&c)!=0) ret=1; return ret; } void ClearMap() { memset(g_map,0,sizeof(g_map)); return; } void CDrawAppView::OnDraw(CDC* pDC) { CDrawAppDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here ClearMap(); DrawSin(); // DrawLine(2,0,3,100); for(int i=0;i<1600;i++) { for(int j=0;j<800;j++) { if(GetPix(i,j)==1) { pDC->SetPixel(i,j,RGB(255,0,0)); } } } } 呵呵,聊天和拨号上网用了10分钟:) |
T: | VC/MFC 编程经验总结2 |
Q: | VC/MFC 编程经验总结1URL: http://expert.csdn.net/Expert/topic/2398/2398212.xml?temp=.3510706 | 在VC的使用过程中,每个人或多或少都会遇到一些麻烦,而这些问题可能其他人也同样遇到过,或许还没能解决。当你发现问题根结所在时,兴奋之余,欢迎你告诉他人同类问题的解决之道。 大家如果有新的发现,请把你的编程经验收藏在这个帖子里吧! 该贴会被放在本版面专题中http://www.csdn.net/Subject/297/index.shtm 奖励办法:对于好的编程经验,贴主可以重新开零分贴,斑竹会将其加入精华或FAQ,奖励可用分(精华100分)、信誉分(FAQ主要问题解决人信誉分加5) |
A: | 主 题: VC小技巧20个<ZT> 作 者: codewarrior (会思考的草) 等 级: 信 誉 值: 103 所属论坛: VC/MFC 基础类 问题点数: 0 回复次数: 11 发表时间: 2003-11-27 10:55:57 一、打开CD-ROM mciSendString("Set cdAudio door open wait",NULL,0,NULL); 二、关闭CD_ROM mciSendString("Set cdAudio door closed wait",NULL,0,NULL); 三、关闭计算机 OSVERSIONINFO OsVersionInfo; //包含操作系统版本信息的数据结构 OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&OsVersionInfo); //获取操作系统版本信息 if(OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { //Windows98,调用ExitWindowsEx()函数重新启动计算机 DWORD dwReserved; ExitWindowsEx(EWX_REBOOT,dwReserved); //可以改变第一个参数,实现注销用户、 //关机、关闭电源等操作 // 退出前的一些处理程序 } 四、重启计算机 typedef int (CALLBACK *SHUTDOWNDLG)(int); //显示关机对话框函数的指针 HINSTANCE hInst = LoadLibrary("shell32.dll"); //装入shell32.dll SHUTDOWNDLG ShutDownDialog; //指向shell32.dll库中显示关机对话框函数的指针 if(hInst != NULL) { //获得函数的地址并调用之 ShutDownDialog = (SHUTDOWNDLG)GetProcAddress(hInst,(LPSTR)60); (*ShutDownDialog)(0); } 五、枚举所有字体 LOGFONT lf; lf.lfCharSet = DEFAULT_CHARSET; // Initialize the LOGFONT structure strcpy(lf.lfFaceName,""); CClientDC dc (this); //Enumerate the font families ::EnumFontFamiliesEx((HDC) dc,&lf, (FONTENUMPROC) EnumFontFamProc,(LPARAM) this,0); //枚举函数 int CALLBACK EnumFontFamProc(LPENUMLOGFONT lpelf,LPNEWTEXTMETRIC lpntm,DWORD nFontType,long lparam) { // Create a pointer to the dialog window CDay7Dlg* pWnd = (CDay7Dlg*) lparam; // add the font name to the list box pWnd ->m_ctlFontList.AddString(lpelf ->elfLogFont.lfFaceName); // Return 1 to continue font enumeration return 1; } 其中m_ctlFontList是一个列表控件变量 六、一次只运行一个程序实例,如果已运行则退出 if( FindWindow(NULL,"程序标题")) exit(0); 七、得到当前鼠标所在位置 CPoint pt; GetCursorPos(&pt); //得到位置 八、上下文菜单事件触发事件:OnContextMenu事件 九、显示和隐藏程序菜单 CWnd *pWnd=AfxGetMainWnd(); if(b_m) //隐藏菜单 { pWnd->SetMenu(NULL); pWnd->DrawMenuBar(); b_m=false; } else { CMenu menu; menu.LoadMenu(IDR_MAINFRAME); 显示菜单 也可改变菜单项 pWnd->SetMenu(&menu); pWnd->DrawMenuBar(); b_m=true; menu.Detach(); } 回复人: codewarrior(会思考的草) ( ) 信誉:103 2003-11-27 11:03:00 得分:0 十一、窗口自动靠边程序演示 BOOL AdjustPos(CRect* lpRect) { //自动靠边 int iSX=GetSystemMetrics(SM_CXFULLSCREEN); int iSY=GetSystemMetrics(SM_CYFULLSCREEN); RECT rWorkArea; BOOL bResult = SystemParametersInfo(SPI_GETWORKAREA, sizeof(RECT), &rWorkArea, 0); CRect rcWA; if(!bResult) { //如果调用不成功就利用GetSystemMetrics获取屏幕面积 rcWA=CRect(0,0,iSX,iSY); } else rcWA=rWorkArea; int iX=lpRect->left; int iY=lpRect->top; if(iX < rcWA.left + DETASTEP && iX!=rcWA.left) { //调整左 //pWnd->SetWindowPos(NULL,rcWA.left,iY,0,0,SWP_NOSIZE); lpRect->OffsetRect(rcWA.left-iX,0); AdjustPos(lpRect); return TRUE; } if(iY < rcWA.top + DETASTEP && iY!=rcWA.top) { //调整上 //pWnd->SetWindowPos(NULL ,iX,rcWA.top,0,0,SWP_NOSIZE); lpRect->OffsetRect(0,rcWA.top-iY); AdjustPos(lpRect); return TRUE; } if(iX + lpRect->Width() > rcWA.right - DETASTEP && iX !=rcWA.right-lpRect->Width()) { //调整右 //pWnd->SetWindowPos(NULL ,rcWA.right-rcW.Width(),iY,0,0,SWP_NOSIZE); lpRect->OffsetRect(rcWA.right-lpRect->right,0); AdjustPos(lpRect); return TRUE; } if(iY + lpRect->Height() > rcWA.bottom - DETASTEP && iY !=rcWA.bottom-lpRect->Height()) { //调整下 //pWnd->SetWindowPos(NULL ,iX,rcWA.bottom-rcW.Height(),0,0,SWP_NOSIZE); lpRect->OffsetRect(0,rcWA.bottom-lpRect->bottom); return TRUE; } return FALSE; } //然后在ONMOVEING事件中使用所下过程调用 CRect r=*pRect; AdjustPos(&r); *pRect=(RECT)r; 十二、给系统菜单添加一个菜单项 给系统菜单添加一个菜单项需要进行下述三个步骤: 首先,使用Resource Symbols对话(在View菜单中选择Resource Symbols...可以显示该对话)定义菜单项ID,该ID应大于 0x0F而小于0xF000; 其次,调用CWnd::GetSystemMenu获取系统菜单的指针并调用CWnd:: Appendmenu将菜单项添加到菜单中。下例给系统菜单添加 两个新的菜单项。 int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct) { … //Make sure system menu item is in the right range. ASSERT(IDM_MYSYSITEM<0xF000); //Get pointer to system menu. CMenu* pSysMenu=GetSystemMenu(FALSE); ASSERT_VALID(pSysMenu); //Add a separator and our menu item to system menu. CString StrMenuItem(_T ("New menu item")); pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_MYSYSITEM, StrMenuItem); … } 十三、运行其它程序 //1、运行EMAIL或网址 char szMailAddress[80]; strcpy(szMailAddress,"mailto:netvc@21cn.com"); ShellExecute(NULL, "open", szMailAddress, NULL, NULL, SW_SHOWNORMAL); //2、运行可执行程序 WinExec("notepad.exe",SW_SHOW); //运行计事本 十四、动态增加或删除菜单 1、 增加菜单 //添加 CMenu *mainmenu; mainmenu=AfxGetMainWnd()->GetMenu(); //得到主菜单 (mainmenu->GetSubMenu (0))->AppendMenu (MF_SEPARATOR);//添加分隔符 (mainmenu->GetSubMenu (0))->AppendMenu(MF_STRING,ID_APP_ABOUT,_T("Always on &Top")); //添加新的菜单项 DrawMenuBar(); //重画菜单 2、 删除菜单 //删除 CMenu *mainmenu; mainmenu=AfxGetMainWnd()->GetMenu(); //得到主菜单 CString str ; for(int i=(mainmenu->GetSubMenu (0))->GetMenuItemCount()-1;i>=0;i--) //取得菜单的项数。 { (mainmenu->GetSubMenu (0))->GetMenuString(i,str,MF_BYPOSITION); //将指定菜单项的标签拷贝到指定的缓冲区。MF_BYPOSITION的解释见上。 if(str=="Always on &Top") //如果是刚才我们增加的菜单项,则删除。 { (mainmenu->GetSubMenu (0))->DeleteMenu(i,MF_BYPOSITION); break; } } 十、获取可执行文件的图标 HICON hIcon=::ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0); if (hIcon &&hIcon!=(HICON)-1) { pDC->DrawIcon(10,10,hIcon); } DestroyIcon(hIcon); |
主 题: 技巧 作 者: fayifu (fayifu) 等 级: 信 誉 值: 100 所属论坛: VC/MFC 基础类 问题点数: 1 回复次数: 3 发表时间: 2003-11-28 09:55:22 1. 如何激活当前屏幕保护程序 //激活当前屏幕保护程序, jingzhou xu PostMessage(WM_SYSCOMMAND,SC_SCREENSAVE,0); 2. 如何禁止/启用屏幕保护及电源管理 static UINT dss_GetList[] = {SPI_GETLOWPOWERTIMEOUT, SPI_GETPOWEROFFTIMEOUT, SPI_GETSCREENSAVETIMEOUT}; static UINT dss_SetList[] = {SPI_SETLOWPOWERTIMEOUT, SPI_SETPOWEROFFTIMEOUT, SPI_SETSCREENSAVETIMEOUT}; static const int dss_ListCount = _countof(dss_GetList); l 禁止屏幕保护及电源管理 { m_pValue = new int[dss_ListCount]; for (int x=0;x<dss_ListCount;x++) { //禁止屏幕保护及电源管理 VERIFY(SystemParametersInfo (dss_SetList[x], 0, NULL, 0)); } delete[] m_pValue; } l 启用屏幕保护及电源管理 { m_pValue = new int[dss_ListCount]; for (int x=0;x<dss_ListCount;x++) { //启用屏幕保护及电源管理 VERIFY(SystemParametersInfo (dss_SetList[x], m_pValue[x], NULL, 0)); } delete[] m_pValue; } 3. 如何激活和关闭IE浏览器 //激活并打开IE void lounchIE() { HWND h=FindWindowEx(NULL,NULL,NULL, "Microsoft Internet Explorer") ; ShellExecute(h,"open","C://simple.html", NULL,NULL,SW_SHOWNORMAL); } //关闭IE及其它应用 void CloseIE() { int app=BSM_APPLICATIONS; unsigned long bsm_app=(unsigned long )app; BroadcastSystemMessage(BSF_POSTMESSAGE,&bsm_app, WM_CLOSE,NULL,NULL); } 4. 如何给树控件加入工具提示 l 首先给树控件加入TVS_INFOTIP属性风格,如下所示: if (!m_ctrlTree.Create(WS_CHILD|WS_VISIBLE| TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS|TVS_INFOTIP, //加入提示TVS_INFOTIP,jingzhou xu(树控件ID:100) CRect(0, 0, 0, 0), &m_wndTreeBar, 100)) { TRACE0("Failed to create instant bar child/n"); return -1; } l 其次加入映射消息声明,如下所示: afx_msg void OnGetInfoTip(NMHDR* pNMHDR,LRESULT* pResult); //树控件上加入提示消息,jingzhou xu ON_NOTIFY(TVN_GETINFOTIP, 100, OnGetInfoTip) //树控件条目上加入提示,jingzhou xu l 最后加入呼应涵数处理: void CCreateTreeDlg::OnGetInfoTip(NMHDR* pNMHDR, LRESULT* pResult) { *pResult = 0; NMTVGETINFOTIP* pTVTipInfo = (NMTVGETINFOTIP*)pNMHDR; LPARAM itemData = (DWORD) pTVTipInfo->lParam; //对应每个条目的数据 HTREEITEM hItem = pTVTipInfo->hItem; CString tip; HTREEITEM hRootItem = m_chassisTree.GetRootItem(); if (hRootItem != pTVTipInfo->hItem) { tip = "树结点的提示"; } else { tip = "树根上的提示"; } strcpy(pTVTipInfo->pszText, (LPCTSTR) tip); } 5. 如何获取系统信息框的路径 #include <atlbase.h> #define IDS_REG_KEY_MSINFO_PATH1 _T( "Software//Microsoft//Shared Tools//MSInfo" ) #define IDS_REG_KEY_MSINFO_PATH2 _T( "Software//Microsoft//Shared Tools Location" ) #define IDS_REG_VAL_MSINFO_PATH1 _T( "Path" ) #define IDS_REG_VAL_MSINFO_PATH2 _T( "MSInfo" ) #define IDS_MSINFO_EXE_NAME _T( "MSInfo32.exe" ) //... BOOL GetSysInfoPath( CString& strPath ) { strPath.Empty(); LPTSTR pszPath = strPath.GetBuffer( MAX_PATH ); CRegKey reg; DWORD dwSize = MAX_PATH; LONG nRet = reg.Open( HKEY_LOCAL_MACHINE, IDS_REG_KEY_MSINFO_PATH1, KEY_READ ); //在注册表中寻找第一个"MSInfo32.exe"位置 if ( nRet == ERROR_SUCCESS ) { #if ( _MFC_VER >= 0x0700 ) nRet = reg.QueryStringValue( IDS_REG_VAL_MSINFO_PATH1, pszPath, &dwSize ); #else nRet = reg.QueryValue( pszPath, IDS_REG_VAL_MSINFO_PATH1, &dwSize ); #endif reg.Close(); } //如果第一次寻找失败,则进行第二次寻找 if ( nRet != ERROR_SUCCESS ) { nRet = reg.Open( HKEY_LOCAL_MACHINE, IDS_REG_KEY_MSINFO_PATH2, KEY_READ ); if ( nRet == ERROR_SUCCESS ) { #if ( _MFC_VER >= 0x0700 ) reg.QueryStringValue( IDS_REG_VAL_MSINFO_PATH2, pszPath, &dwSize ); #else reg.QueryValue( pszPath, IDS_REG_VAL_MSINFO_PATH2, &dwSize ); #endif //路径名不包括EXE文件名 if ( nRet == ERROR_SUCCESS ) VERIFY( ::PathAppend( pszPath, IDS_MSINFO_EXE_NAME ) ); reg.Close(); } } strPath.ReleaseBuffer(); strPath.FreeExtra(); //检查文件是否有效. return ::PathFileExists( strPath ); } 6. 如何直接运行一个资源中的程序 bool Run() { CFile f; char* pFileName = "Execution.exe"; if( !f.Open( pFileName, CFile::modeCreate | CFile::modeWrite, NULL ) ) { AfxMessageBox("Can not create file!"); return 0; } CString path = f.GetFilePath(); HGLOBAL hRes; HRSRC hResInfo; //获取应用实例 HINSTANCE insApp = AfxGetInstanceHandle(); //寻找EXE资源名 hResInfo = FindResource(insApp,(LPCSTR)IDR_EXE4,"EXE"); hRes = LoadResource(insApp,hResInfo ); // Load it DWORD dFileLength = SizeofResource( insApp, hResInfo ); //计算EXE文件大小 f.WriteHuge((LPSTR)hRes,dFileLength); //写入临时文件 f.Close(); HINSTANCE HINSsd = ShellExecute(NULL, "open",path, NULL, NULL, SW_SHOWNORMAL);> //运行它. return 1; } 7. 如何遍历整个目录 #include <windows.h> #include <shlobj.h> //浏览目录. void BrowseFolder( void ) { TCHAR path[MAX_PATH]; BROWSEINFO bi = { 0 }; bi.lpszTitle = ("递归调用所有目录"); LPITEMIDLIST pidl = SHBrowseForFolder ( &bi ); if ( pidl != 0 ) { //获取目录路径 SHGetPathFromIDList ( pidl, path ); //设置为当前路径 SetCurrentDirectory ( path ); //搜索所有子目录 SearchFolder( path ); //释放内存 IMalloc * imalloc = 0; if ( SUCCEEDED( SHGetMalloc ( &imalloc )) ) { imalloc->Free ( pidl ); imalloc->Release ( ); } } //搜索其下所有子目录及文件. void SearchFolder( TCHAR * path ) { WIN32_FIND_DATA FindFileData; HANDLE hFind; TCHAR filename[ MAX_PATH + 256 ]; TCHAR pathbak[ MAX_PATH ]; //复制初始用户选择目录 strcpy( pathbak, path ); //寻找第一个文件 hFind = FindFirstFile ( "*.*", &FindFileData ); //搜索所有文件及子目录 do { if ( hFind != INVALID_HANDLE_VALUE ) { //如果是当前目录或父目录,跳过 if ( ! ( strcmp( FindFileData.cFileName, "." ) ) || ! ( strcmp( FindFileData.cFileName, ".." ) ) ) { continue; } //恢复初始用户选择目录 strcpy( path, pathbak ); //列出所有发现的文件 sprintf( path, "%s//%s", path, FindFileData.cFileName ); //如果SetCurrentDirectory成功的话,则它是一个目录,递归调用继续搜索子目录 if ( ( SetCurrentDirectory( path ) ) ) { SearchFolder( path ); } //插入文件及路径名到列表框m_listbox_hwnd中 SendMessage( m_listbox_hwnd, LB_ADDSTRING, 0, path ); //<--INSERT WHAT YOU WANT DONE HERE! } } while ( FindNextFile ( hFind, &FindFileData ) && hFind != INVALID_HANDLE_VALUE ); FindClose ( hFind ); } 8. 如何禁止/启用系统热键 bool bOld; l 禁止系统热键 //屏蔽掉系统键 SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,true,&bOld,SPIF_UPDATEINIFILE); l 启用系统热键 //恢复系统热键 SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,false,&bOld,SPIF_UPDATEINIFILE); 9. 如何隐藏/显示WINDOWS系统任务栏 l 隐藏系统任务栏 //隐藏WINDOWS系统任务栏 ::ShowWindow (::FindWindow("Shell_TrayWnd",NULL),SW_HIDE); l 显示系统任务栏 //恢复WINDOWS系统任务栏正常显示 ::ShowWindow (::FindWindow("Shell_TrayWnd",NULL),SW_SHOW); | |
T: | 各位大侠,还是读写文件问题,再百分相送 |
Q: | 各位大侠,我在VC里面编程 想把一个文件里面的所有大写字符都转换成小写 用打开一个文件读写的方法 FILE * ff; ff=fopen("a.txt","w"); if(ff == NULL) return 0; char c; while(!feof(ff)){ c=fgetc(ff); fseek(ff,-1,SEEK_CUR); fputc(tolower(c),ff); fseek(ff,1,SEEK_CUR); } fclose(ff); 是个死循环了 如何能不用中间文件 通过文件位置指针 完成一个文件的读写?? 望各位指点迷津 问题解决立刻给分 |
A: | 害我睡不成觉,赔! 我调试通过了。使用内存影像文件 #include "stdafx.h" #include "windows.h" int main(int argc, char* argv[]) { HANDLE hFile = CreateFile("J://a.txt", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL); int iLen=GetFileSize(hFile,NULL)+1; HANDLE hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE, 0, iLen, NULL); // 释放文件内核对象 CloseHandle(hFile); __int64 qwFileOffset = 0; PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS, (DWORD)(qwFileOffset>>32), (DWORD)(qwFileOffset&0xFFFFFFFF), iLen); strcpy((char*)(pbFile+qwFileOffset),_strlwr( _strdup( (char*)(pbFile+qwFileOffset)))); UnmapViewOfFile(pbFile); CloseHandle(hFileMapping); return 0; } |
T: | 一个文件异常(CFileException)的问题,在线等待! |
Q: | try { CFile::Remove(filename); } catch (CFileException& Exception) { switch(Exception.m_cause) { case CFileException::accessDenied: TRACE("Access denied!/n"); return FALSE; default: TRACE("Remove default Exception!/n"); return FALSE; } } 我在一个程序要删除另一个程序正在读的文件, 用上面的方法捕获异常, 为什么总是捕获不到, 删除文件是程序抛出 Abnormal program exception, 的C++ runtime error提示, 在TRACE中能看到windows给出的accessDenied异常, 但我的程序总是捕获不到,为什么? |
A: | void CDelFileDlg::OnButton1() { // TODO: Add your control notification handler code here try { CFile::Remove("E://Program Files//UltraEdit//UEDIT32.EXE"); } catch(CFileException* e) { switch(e->m_cause) { case CFileException::accessDenied: TRACE("Access denied!/n"); return ; default: TRACE("Remove default Exception!/n"); return ; } } } 我试过他们的,确实不行 不过我现在的行:) |
T: | DEBUG模式下编译、链接、运行都没问题。可是在Release模式下,就会出现非法操作??? |
Q: | 这个问题很复杂,我都有点不知道该怎么描述它。所以不求你们能给我一个精确的答案,我只想要一个解决问题的思路。因为我以前从未遇到过这种情况。 问题是这样的: 我的程序已经写完了,在DEBUG版本下编译、链接、运行都没问题。现在我要发布这个程序,当然得在Release模式下编译它。这时,编译、连接都没问题,没有任何警告与错误。可是当它运行起来的时侯,如果我执行了一个特定的操作:程序会在系统托盘里添加一个图标,鼠标右击这个图标会出现一个菜单,当单击其中一个菜单项时,程序就会出现非法操作。我把对这个命令消息的处理过程清空,即什么操作都不执行,只是一个空函数。它也会出现非法操作。可是,如果在DEBUG模式下,无论怎样都不会出错(不管函数内有没有代码)。 这个问题真是有些棘手,因为在Release模式下没法调试,要调试的话,也只能是汇编级调试,我不会汇编。现在的问题是,我该如何着手从那个方向去解决这个问题呢? |
A: | 这个问题很复杂,我都有点不知道该怎么描述它。所以不求你们能给我一个精确的答案,我只想要一个解决问题的思路。因为我以前从未遇到过这种情况。 问题是这样的: 我的程序已经写完了,在DEBUG版本下编译、链接、运行都没问题。现在我要发布这个程序,当然得在Release模式下编译它。这时,编译、连接都没问题,没有任何警告与错误。可是当它运行起来的时侯,如果我执行了一个特定的操作:程序会在系统托盘里添加一个图标,鼠标右击这个图标会出现一个菜单,当单击其中一个菜单项时,程序就会出现非法操作。我把对这个命令消息的处理过程清空,即什么操作都不执行,只是一个空函数。它也会出现非法操作。可是,如果在DEBUG模式下,无论怎样都不会出错(不管函数内有没有代码)。 这个问题真是有些棘手,因为在Release模式下没法调试,要调试的话,也只能是汇编级调试,我不会汇编。现在的问题是,我该如何着手从那个方向去解决这个问题呢? |
T: | [VC新手]问矢量轮廓描述与填充算法 |
Q: | 请问 Windows 下矢量字体是如何描述的,如以 TrueType 字体为例,其格式如何? 我要做的应用是最终控制物理器件的运动轨迹走出汉字(大小可变)的外形轮廓,然后以水平、垂直或45°方向的直线填充(密度可调),请问该用什么算法实现? 由于我对矢量格式一无所知,希望大家能教以方法,或提供基础性资料,网址亦可 |
A: | 要实践你的功能,不一定要用GetPath,我的思路是,先在Form上画出你需要的字, 然后用扫描线的方法复制到你的设备上,设备只需用MoveTo及LineTo void __fastcall TForm1::Button1Click(TObject *Sender) { String ch="噗"; //可以多个字符 Canvas->Font->Name="宋体"; Canvas->Font->Color=clBlack; Canvas->Font->Size=40; Canvas->TextOut(100,100,ch); int w=Canvas->TextWidth(ch); int h=Canvas->TextHeight(ch); TColor c,oldc; for(int j=0;j<h;j++) { oldc=c=clWhite; for(int i=0;i<w;i++) { c=Canvas->Pixels[100+i][100+j]; if (c!=oldc) { if (c==clBlack) Canvas->MoveTo(300+i,100+j); //在你的设备上MoveTo else Canvas->LineTo(300+i,100+j); //在你的设备上LineTo oldc=c; } } } } |
T: | 如何在主程序中释放DLL中new的内存? |
Q: | 兄弟在主程序中用loadlibrary加载了一个DLL,然后在调用该DLL的一个函数时,返回在该函数中使用new操作符得到的一个内存指针,在主程序中使用完该指针后用delete释放时出现debug错误,这怎么办? |
A: | 3:Dll分配的内存块,应用程序释放,结果报异常。 用GlobalAlloc()代替new, 用GlobalFree() 代替delete就不会出错了 其实还有一个办法,就是把dll的Settings的C/C++选项卡的Code Generation的Use Run-time liberary改成Debug Multithreaded DLL,在Release版本中改成Multithreaded DLL,就可以直接使用new和delete了,没问题 比较规范点的做法一般是DLL分配的内存由DLL释放。在DLL中加一个函数释放内存不是更好吗。 给分吧,呵呵 |
T: | mfc dll如何导出类 |
Q: | 我要在mfc dll中,非mfc 扩展dll,也不是非mfc dll,导出一个类,如何实现呀 |
A: | 呵呵,想不到我的东西也要被别人广为传抄了: http://expert.csdn.net/Expert/topic/2514/2514628.xml?temp=.4149897 导出类很简单的 在你的DLL中Alt+F7中有一个C/C++中preprocessor definitions编辑框添加AAA_EXPORTS定义,然后在头文件类定义之前添加 #ifdef AAA_EXPORTS #define AAA_API __declspec(dllexport) #else #define AAA_API __declspec(dllimport) #endif 然后在你的类的声明前添加AAA_API ,就象上面一样,在主工程中包括这个头文件,主工程中在ALT+F7的LINK选项卡添加该DLL的.LIB文件。OK |
T: | 有人做过线形算法吗? |
Q: | 有人做过线形算法吗?欢迎提供详细思路 |
A: | 这些代码你研究一下 WINNT下,可以用以下方式创建画笔 LOGBRUSH brush; brush.lbColor=DrawColor; brush.lbStyle=BS_SOLID; mPen.CreatePen(PS_GEOMETRIC|PS_USERSTYLE|PS_ENDCAP_FLAT,(int)LineWide,&brush,i,PenStyle); Win98中,给DC设置合适的笔宽,选择实线,下面函数可以根据PenStyle数组给定长度值画直线。如果画曲线或者折线,需要把曲线离散成直线段,根据上次画线返回值确定本次画线的起始值,就可以了 #include "math.h" DWORD PenStyle[16] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}; typedef struct xyz { double x; double y; double z; } XYZ,*PXYZ,**PPXYZ; //按照PenStyle[]画一条从p1点到p2点的直线 //例如PenStyle[0]=5,PenStyle[1]=2表示按照长度为5的实线、长度为2的间隔形成的线型画线 //_____ _____ _____ _ //并且指定从线型的何处画,例如iStart=6从Penstyle[1]处的第二个空格开始画 //iStart取值范围为0到一个线型的总长度-1 //返回值:线型总长度与剩余最后一段线长度之差,表示下一次画线应该指定的从何处开始画 int DrawLineA(CDC* pDC,POINT p1,POINT p2,int iStart) { int i=0; int iEnd=0;//返回值,表示最后一段不完全的线段的长度 //计算直线长度 double dDistance=sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y)); int iLineType=0;//线型的长度 if(dDistance<2) { for(i=0;i<16;i++) { if(PenStyle[i]==0)break; iLineType+=PenStyle[i]; } iEnd=(int(iStart-dDistance))%iLineType; if(iEnd<0)iEnd+=iLineType; return iEnd; } double ddltx[16]={0,0,0,0,//每一段线型的x距离 0,0,0,0, 0,0,0,0, 0,0,0,0}; double ddlty[16]={0,0,0,0,//每一段线型的y距离 0,0,0,0, 0,0,0,0, 0,0,0,0}; double dXScale=(p2.x-p1.x)/dDistance;//x方向长度和总长度比例 double dYScale=(p2.y-p1.y)/dDistance;//y方向长度和总长度比例 //计算每一段线型的x、y距离及线型的长度 for(i=0;i<16;i++) { if(PenStyle[i]==0)break; ddltx[i]=PenStyle[i]*dXScale; ddlty[i]=PenStyle[i]*dYScale; iLineType+=PenStyle[i]; } iEnd=(int(dDistance+iStart))%iLineType; if(iEnd<0)iEnd+=iLineType; XYZ pp={0,0,0};//第一段之前的完整线型开始点 pDC->MoveTo(p1); int iLength=-iStart;//已经画的线段的长度 pp.x=iLength*dXScale+p1.x; pp.y=iLength*dYScale+p1.y; for(;;) { for(i=0;i<16;i++) { if(PenStyle[i]==0)break; pp.x+=ddltx[i]; pp.y+=ddlty[i]; iLength+=PenStyle[i]; if(i%2==0) { if(iLength>0) { if(iLength<dDistance) { pDC->LineTo(pp.x,pp.y); } else { pDC->LineTo(p2); return iEnd; } } }else { if(iLength>0) { if(iLength<dDistance) { pDC->MoveTo(pp.x,pp.y); } else { pDC->MoveTo(p2); return iEnd; } } } } } return iEnd; } |