每日一点

2012-9-6:

如果想知道你的对象是否获得焦点,可以用::GetFocus()函数的返回值与你的对象的this->m_hWnd来进行对比:

if(this->m_hWnd==::GetFocus())
{
     //说明已经获得焦点
}


2012-9-7:

判断窗口是否存在与显示:

BOOL IsWindow(HWND hWnd /);//判断该窗口是否存在
BOOL IsWindowVisible(HWND hWnd );//函数来判断某对话框是显示还是隐藏

2012-10-24:

CreateProcess函数

CreateProcess函数用于创建进程:
BOOL CreateProcess(
PCTSTR pszApplicationName,
PTSTR pszCommandLine,
PSECURITY_ATTRIBUTES psaProcess,
PSECURITY_ATTRIBUTES psaThread,
BOOL bInheritHandles,
DWORD fdwCreate,
PVOID pvEnvironment,
PCTSTR pszCurDir,
PSTARTUPINFO psiStartInfo,
PPROCESS_INFORMATION ppiProcInfo);

线程调用CreateProcess时,系统会创建一个进程内核对象,将其引用计数初始化为1(进程内核对象并不是进程本身,它只是操作系统用来管理进程的数据结构,其中包含了进程的一些统计信息)。然后系统为新进程开辟虚拟地址空间,并将可执行文件的代码和数据以及所需的DLL装载到该地址空间中。接着系统为进程主线程创建线程内核对象,并将其引用计数初始为1(同进程一样,线程内核对象也不是线程本身,而且操作系统用来管理线程的数据结构)。主线程将链接器设置的入口点函数作为C/C++运行时启动函数调用,这些启动函数最终又调用代码中的入口点函数如WinMain、wWinMain、main和 wmain。当操作系统成功创建了新的进程和主线程后,CreateProcess返回TRUE。以上是CreateProcess的简要介绍,下面我们来详细讨论它的参数。

pszApplicationName和pszCommandLine
  pszApplicationName和pszCommandLine分别表示进程使用的可执行文件名和向其传递的命令行字符串,我们先来看看 pszCommandLine参数。注意pszCommandLine是PTSTR,这意味着你必须为其传递指向非常量字符串的地址。(居然就犯了这样一个错误,果然是莫在浮沙筑高台啊!) CreateProcess内部会更改向其传递的命令行字符串,但在CreateProcess返回之前,它会将该字符串恢复原样。这一点是非常重要的,因为如果你向CreateProcess传递的命令行字符串位于进程的只读存储区,就会发生Access Violation错误。比如,下面的代码执行时会触发Access Violation,因为微软的C/C++编译器会把常量字符串放入只读存储区(注意早期的微软C/C++编译器会将常量字符串放在可读写存储区,因此下面的代码在旧的编译环境下不会出错):
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(NULL, TEXT("NOTEPAD"), NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);

解决这个问题的方法很简单,将命令行字符串复制到临时缓冲区既可,如下所示:
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR szCommandLine[] = TEXT("NOTEPAD");
CreateProcess(NULL, szCommandLine, NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);

微软在其C++编译器选项中提供了/GF开关,/GF打开时,程序中所有用到的常量字符串将只维护单一副本,且位于只读存储部分。在调用 CreateProcess时,开发人员应该打开/GF开关并使用缓冲区。我们希望微软在未来版本的Windows中会改进CreateProcess,使其接受常量字符串作为命令行参数,并在其内部分配/释放临时缓冲区而不是让API调用者来做。另外,假如你使用常量ANSI字符串作为 CreateProcess参数,并不会发生Access Violation错误,我们在前面的章节已经提到过,许多WinAPI函数的ANSI版本会将ANSI参数转换为UNIDOE编码后调用其 Unicode版本,CreateProcess会把ANSI字符串转换为Unicode编码后放在临时缓冲区,并调用Unicode版的 CreateProcess,因此不会触发Access Violation。
  pszCommandLine参数指定了 CreateProcess创建新进程所需的完整命令行。当CreateProcess解析该参数时,它会检查命令行参数中的第一个标记,并将其作为进程要执行的可执行文件名,如果该文件名没有指定后缀,函数将把它当作exe文件。CreateProcess会按下面的顺序查找该文件:
1. 包含当前进程可执行文件的目录
2. 当前进程的当前目录
3. Windows系统目录,既GetSystemDirectory返回的目录
4. Windows目录
5. PATH环境变量列出的目录
当然,如果文件名包含了完整路径,系统将会在该路径中查找文件而不会再做上面的搜索。如果系统找到了可执行文件,它会创建一个新的进程并把可执行文件的代码和数据映射到进程的地址空间,然后调用CRT启动函数(linker选项卡中的入口点函数),接着CRT启动函数检查命令行参数,过滤掉其中的可执行文件部分,并把剩下字符串的地址作为pszCmdLine传给wWinMain/WinMain。

以上情形都是在pszApplicationName为NULL时发生的。 pszApplicationName指定了进程要执行的可执行文件的名称,假如没有指定文件后缀,系统并不会做任何处理。 pszApplicationName不包含完整路径时,CreateProcess只从当前目录中查找可执行文件,查找失败时函数失败并返回 FALSE。即使指定了pszApplicationName,CreateProcess仍然会将pszCommandLine参数作为新进程的命令行。比如下面的代码:
// Make sure that the path is in a read/write section of memory.
TCHAR szPath[] = TEXT("WORDPAD README.TXT");

// Spawn the new process.
CreateProcess(TEXT("C:\\WINDOWS\\SYSTEM32\\NOTEPAD.EXE"),szPath,...);

执行上面代码时,系统会打开notepad.exe(记事本),但它的命令行却是WORDPAD README.TXT(WORDPAD是写字板),这看上去非常奇怪,但CreateProcess就是这样工作的。这种 pszApplicationName提供的特性被用来支持Windows的POSIX子系统。

2.12-10-26:

Asymptote Tips:

asymptote 是一种类似于metapost的科学绘图语言,由于其语法融合了C的特性,所以更加好学,而且asymptote有强大的3D绘图能力,尤其是可以绘制真3D图像,这个特性是metapost所不及的

 dot(pair,UnFill)中的UnFill是把点挖空,而不是填充为白色,这个特点是很独到的

 为了给角加标注,需要引入geometry宏包,为了方便画函数图,需要引入graph宏包,为绘制隐函数,需要引入contour宏包,阴影填充,引入patterns宏包

 for(int i=0, i<4; br="" /> %默认的线宽是0.5bp(1bp=1/72inch)

 ^^ 二元运算符,它要求画笔从左边路径的终点移动(而不绘制出来或影响终点的曲率)到右边路径的起点,可以用来将若干 Asymptote 路径汇集到一个 path[] 数组中

 Asymptote内部的变量名是大小写敏感的

 对于pair型变量p和triple型变量t而言,取分量可以简单的:p.x,p.y;t.x,t.y,t.z

 import three之后,X,Y,Z三个字母就已经被定义为单位向量了

b=3*++a;等价于: a=a+; b=3*a


2012-11-3:VC创建路径与判断路径存不存在 

以下程序得到运行程序的当前路径,并在当前路径文件夹下创建tmp文件夹,判断存不存在。

CString CurPath;
DWORD size=MAX_PATH;
::GetModuleFileName(NULL,CurPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);
int pos=CurPath.ReverseFind('\\');
CurPath=CurPath.Left(pos+1);
CString tmp=CString("tmp\\");
CurPath+=tmp;
CFileFind find;
if(!find.FindFile(CurPath))
{
::CreateDirectory(CurPath,NULL);
}
m_tmpImagePath=CurPath;


2012-11-4 获得文件夹得路径

//选择文件夹
CString GetDirectory()
{
BROWSEINFO bi;
char name[MAX_PATH];
ZeroMemory(&bi,sizeof(BROWSEINFO));
bi.hwndOwner = AfxGetMainWnd()->GetSafeHwnd();
bi.pszDisplayName = name;
bi.lpszTitle = "选择文件夹目录";
bi.ulFlags = BIF_RETURNFSANCESTORS;
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if(idl == NULL)
return "";
CString strDirectoryPath;
SHGetPathFromIDList(idl, strDirectoryPath.GetBuffer(MAX_PATH));
strDirectoryPath.ReleaseBuffer();
if(strDirectoryPath.IsEmpty())
return "";
if(strDirectoryPath.Right(1)!="\\")
strDirectoryPath+="\\";

return strDirectoryPath;
}


2012-12-8 修改VC生成的exe的默认名称:

工程属性->链接器->常规->输出文件


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现Java导出Excel单表头或多表头,可以使用Apache POI库。下面是一个简单的示例代码,可以导出带有单表头和多表头的Excel文件: ```java public static void exportExcel(List<List<String>> data, List<String> headers, String filePath) throws IOException { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); // 创建单表头 Row headerRow = sheet.createRow(0); for (int i = 0; i < headers.size(); i++) { Cell cell = headerRow.createCell(i); cell.setCellValue(headers.get(i)); } // 创建多表头 if (data.size() > 0) { Row subHeaderRow = sheet.createRow(1); List<String> subHeaders = data.get(0); for (int i = 0; i < subHeaders.size(); i++) { Cell cell = subHeaderRow.createCell(i); cell.setCellValue(subHeaders.get(i)); } } // 填充数据 int rowIndex = data.size() > 0 ? 2 : 1; for (List<String> rowData : data) { Row row = sheet.createRow(rowIndex++); for (int i = 0; i < rowData.size(); i++) { Cell cell = row.createCell(i); cell.setCellValue(rowData.get(i)); } } // 输出文件 try (FileOutputStream outputStream = new FileOutputStream(filePath)) { workbook.write(outputStream); } } ``` 这个方法接受一个包含数据的二维列表、表头列表和输出文件路径的参数。它首先创建一个新的工作簿和一个新的工作表,然后填充单表头和多表头行,最后填充数据并将结果写入文件。注意,在创建多表头行时,我们需要检查数据列表是否为空,以避免出现数组越界异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值