Textreplace插件的使用:
1 !include "TextReplace.nsh"
2
3 ${textreplace::ReplaceInFile} "c:\1.txt" "c:\1.txt" "%Install%" "替換的內容" "/S=1" $4
4 ${textreplace::FreeReadBuffer} "$4"
5 ${textreplace::Unload}
posted @
2012-05-04 18:12 王海光 閱讀(2053) |
評論 (0) |
編輯 收藏
在域環境下,有時受限賬戶對文件夾需要讀、寫操作權限,下面為修改文件夾訪問權限代碼:
1 ReadINIStr $1 "$EXEDIR\Test.ini" "Directory" "DirectoryName"
2 ReadINIStr $2 "$EXEDIR\Test.ini" "Directory" "DriverDirectoryName"
3 ReadEnvStr $3 ALLUSERSPROFILE
4 CreateDirectory "$3\$1"
5 CreateDirectory "$3\$2"
6 ;Make the directory read write accessible by everyone
7 AccessControl::GrantOnFile \
8 "$3\$1" "everyone" "GenericRead + GenericWrite"
9
10 AccessControl::GrantOnFile \
11 "$3\$2" "everyone" "GenericRead + GenericWrite"
在XP64位系統下,如果將提升權限的操作放到禁止重定向下面,修改文件夾權限會失敗。如果對C:\WINDOWS\System32下面的配置文件進行修改,則必須放到禁止重定向下面修改。否則修改的將是C:\WINDOWS\SysWOW64下的配置文件。
posted @
2012-05-04 13:16 王海光 閱讀(5869) |
評論 (2) |
編輯 收藏
摘要: $INSTDIR
安裝目錄 ($INSTDIR 可以使用 StrCpy、 ReadRegStr、 ReadINIStr 等等來更改。例如在 .onInit 函數里可以用來做高級的檢測安裝定位)。
注意在卸載程序代碼里,$INSTDIR 為卸載程序所在的目錄而不是在安裝程序里所指定的目錄。例如, 如果你把卸載程序放在 $WINDIR 里并且用戶沒有移動它,那么在卸載程序里 $INSTDIR 就等于 $WINDIR。如果你要把卸載程序放到另外的位置,那么你應該先把安裝程序的 $INSTDIR 值寫入注冊表或者其它容易保存的地方,然后在卸載程序里讀取該值并賦值給卸載程序里的 $INSTDIR。
閱讀全文
posted @
2012-05-03 17:30 王海光 閱讀(1190) |
評論 (0) |
編輯 收藏
摘要: 本文轉自:http://topic.csdn.net/t/20031208/15/2540422.html關于CString總結前言:串操作是編程中最常用也最基本的操作之一 做為VC程序員,無論是菜鳥或高手都曾用過CString.而且好像實際編程中很難離得開它(雖然它不是標準C++中的庫).因為MFC中提供的這個類對我們操作字串...
閱讀全文
posted @
2012-04-28 09:53 王海光 閱讀(493) |
評論 (0) |
編輯 收藏
摘要: 轉自:http://www.shnenglu.com/humanchao/archive/2011/08/03/152332.html
深入分析MFC文檔視圖結構(項目實踐)
k_eckel:http://www.mscenter.edu.cn/blog/k_eckel
文檔視圖結構(Document/V...
閱讀全文
posted @
2012-04-26 14:06 王海光 閱讀(512) |
評論 (0) |
編輯 收藏
MFC socket的使用方法服務器端:
在.h文件中。
1 struct ListeningThreadStruct
2 {
3 CString sSaveDir;
4 int nListenPort;
5 };
6 UINT ListeningThreadProc(LPVOID lparam);
7 struct FileTransferThreadStruct
8 {
9 CString sSaveDir;
10 SOCKET hSOCKET;
11 };
12
13 UINT FileTransferThread(LPVOID lparam);
在.cpp文件中。
1 UINT CSocketFun::ListeningThreadProc(LPVOID lparam)
2 {
3 ListeningThreadStruct *pPara = (ListeningThreadStruct*)lparam;
4 int nListenPort = pPara->nListenPort;
5 CString sSaveDir = pPara->sSaveDir;
6 delete pPara;
7 pPara = NULL;
8
9 SocketThreadInit();
10 try
11 {
12 CSocket liseningSocket;
13 if ( !liseningSocket.Create(nListenPort) )
14 {
15 LOG("創建TCP端口失敗, 可能是端口%d被占用", nListenPort);
16 return 1;
17 }
18
19 if ( !liseningSocket.Listen(5) )
20 {
21 LOG("啟動Socket監聽失敗");
22 return 1;
23 }
24
25 while(true)
26 {
27 CSocket clientSocket;
28 if ( liseningSocket.Accept(clientSocket) )
29 {
30 FileTransferThreadStruct *pFileTrans = new FileTransferThreadStruct;
31 pFileTrans->hSOCKET = clientSocket.Detach();
32 pFileTrans->sSaveDir = sSaveDir;
33
34 AfxBeginThread(FileTransferThread2, (LPVOID)pFileTrans);
35 }
36 else
37 {
38 liseningSocket.Close();
39 break;
40 }
41 }
42 }
43 catch(
)
44 {
45 LOG("監控Socket線程收到異常, 監聽結束");
46 return 0;
47 }
48 return 0;
49 }
50
51
52 UINT CSocketFun::FileTransferThread2(LPVOID lparam)
53 {
54 FileTransferThreadStruct *pPara = (FileTransferThreadStruct*)lparam;
55 SOCKET sock = pPara->hSOCKET;
56 CString sSaveDir = pPara->sSaveDir;
57 delete pPara;
58 pPara = NULL;
59
60 SocketThreadInit();
61
62 CSocket aSocket;
63 aSocket.Attach(sock);
64
65 char buffer[SERVER_SOCKET_BUFFERSIZE] = {'\0'};
66 int nLen = aSocket.Receive(buffer, MAX_PATH);
67 } 調用線程.cpp文件中。
1 ListeningThreadStruct *pPara = new ListeningThreadStruct;
2 pPara->sSaveDir = m_sSaveDir;
3 pPara->nListenPort = m_nListenPort;
4
5 CWinThread *pThread = AfxBeginThread(ListeningThreadProc, (LPVOID)pPara);
客戶端:
示例代碼:
1 #define OutStr(x,
) \
2 {\
3 CString sMsg; \
4 sMsg.Format(x, __VA_ARGS__); \
5 if (sMsg.GetLength() < (int)nErrBufLen) \
6 strcpy_s(pErrorBuf, nErrBufLen, sMsg); \
7 else \
8 strcpy_s(pErrorBuf, nErrBufLen, "緩沖區大小不足"); \
9 }
10
11
12 AFX_MANAGE_STATE(AfxGetStaticModuleState());
13
14 if (!AfxSocketInit())
15 {
16 return 1 ;
17 }
18
19 SocketThreadInit();
20
21 CSocket aSocket;
22 if (!aSocket.Create())
23 {
24 OutStr("創建socket失敗");
25 return 1;
26 }
27
28 if (!aSocket.Connect(sServerIP, nPort))
29 {
30 OutStr("連接服務器失敗IP %s 端口 %d", sServerIP, nPort);
31 return 1;
32 }
33
34 CFile file;
35 if (!file.Open(sFile, CFile::modeRead))
36 {
37 OutStr("發送文件時, 文件%s打開失敗", sFile);
38 return 1;
39 }
40
41 // 1. send file name
42 char fileName[MAX_PATH] = {'\0'};
43 strcpy_s( fileName, MAX_PATH, CCommonFun::GetFileFullName(sFile) );
44 if ( SOCKET_ERROR == aSocket.Send(fileName, MAX_PATH) )
45 {
46 OutStr("文件名通過socket發送失敗");
47 return 1;
48 }
49
50 // 2. send file size
51 ULONGLONG ulFileLen = file.GetLength();
52 if (SOCKET_ERROR == aSocket.Send(&ulFileLen, sizeof(ULONGLONG) ) )
53 {
54 OutStr("文件長度通過socket發送失敗");
55 return 1;
56 }
57
58 try
59 {
60 char buffer[CLIENT_SOCKET_BUFFERSIZE] = {'\0'};
61 UINT nTotalLen = 0;
62 UINT nLen = 0;
63 while ((nLen = file.Read(buffer, CLIENT_SOCKET_BUFFERSIZE)) > 0)
64 {
65 if (SOCKET_ERROR == aSocket.Send(buffer, nLen))
66 {
67 OutStr("文件數據通過socket發送失敗, 已發送%d", nTotalLen);
68 return 1;
69 }
70
71 nTotalLen += nLen;
72 }
73 }
74 catch (
)
75 {
76 OutStr("發送文件數據時收到一個異常, 發送失敗");
77 return 1;
78 }
79
80 #define SOCKET_OK_BUFFERSIZE 1024
81 char szOK[SOCKET_OK_BUFFERSIZE] = {'\0'};
82 int nLen = aSocket.Receive(szOK, SOCKET_OK_BUFFERSIZE);
83 if (CString(szOK) != "ok")
84 {
85 OutStr("未收到合法的服務器回文, 發送失敗");
86 return 1;
87 }
posted @
2012-04-26 13:58 王海光 閱讀(1875) |
評論 (0) |
編輯 收藏
MFC一種線程的使用方法在.h文件中。
1 struct MonitorPara
2 {
3 enum SaveType
4 {
5 OnlySend,
6 SendSave,
7 SendErrorSave
8 };
9
10 int m_nListenPort; // monitor local ip port
11 CString m_sServerIP; // send data server ip
12 int m_nServerPort; // send data server port
13
14 SaveType m_SaveType;
15 CString m_sDataBufDir;
16 };
17
18 static UINT ListeningThreadProc(LPVOID lparam);
在.cpp文件中。
1 UINT CSocketPrinter::ListeningThreadProc(LPVOID lparam)
2 {
3 //CFileWatcher* obj = (CFileWatcher*)lParam;
4 CSocketPrinter::MonitorPara para = *((CSocketPrinter::MonitorPara*)lparam);
5
6
7 }
8
9 BOOL CSocketPrinter::StartMonitor(const MonitorPara ¶)
10 {
11 CWinThread* pThread = AfxBeginThread(ListeningThreadProc, (LPVOID)¶);
12
13 return (pThread && pThread->m_hThread);
14 }
調用線程.cpp文件中。
1 CSocketPrinter obj;
2 CSocketPrinter::MonitorPara para;
3
4 HANDLE h_Thread = NULL;
5 h_Thread = obj.StartMonitor(para);
6
7 if (!h_Thread)
8 {
9 LOG("獲取線程句柄出錯");
10 return;
11 }
強制結束線程
1 ::TerminateThread(h_Thread, 0);
posted @
2012-04-26 13:35 王海光 閱讀(510) |
評論 (0) |
編輯 收藏
64位操作系統下拷貝文件重定向問題問題:安裝打印機驅動時,系統拷貝驅動文件到系統目錄C:\Windows\System32\spool\drivers,有的驅動會出現安裝驅動不成功的現象。
原因:64位操作系統下沒有禁止重定向。
在程序中加上下面代碼解決重定向問題。
1 KWow64FsRedrt redrt;
2 if (redrt.Init())
3 {
4 redrt.Close();
5 }
32位的Windows系統沒有重定向這個說法。
其他文章:
http://blog.csdn.net/hcyang/article/details/4578796 http://www.cnblogs.com/BeyondTechnology/archive/2010/10/21/1857881.html
posted @
2012-04-25 16:27 王海光 閱讀(645) |
評論 (0) |
編輯 收藏
結構體CString問題
1 struct sTest
2 {
3 CString addr;
4 int port;
5 };
定義CString addr時,編譯器會在棧里分配一塊內存空間,然后調用CString的默認構造函數初始化addr,此時Cstring內部的m_pchData指向一個空字串 " ",而不是NULL。cstring在結構里也是一樣的,結構無論是從棧中分配如 :
ME_REFRESH lpmerefresh
或從堆中分配 :
lpmerefresh=new ME_REFRESH;
type為cstring的分量都會被調用默認構造函數初始化name,使Cstring內部的m_pchData指向一個空字串 " ",該空字串是afxEmptyString的m_pchData。memset CString時,該m_pchData便指向了NULL,那么就表明該CString的值被破壞了,所以報錯。
結構體成員如果僅僅是基本類型成員可以直接memset(ST,0,sizeof(ST)),但結構體里面包含有指針,直接memset是不行的,因為指針成員的sizeof都是4字節。你應該專門對指針成員進行memset,sizeof對于包含指針的結構獲得的長度不是你想要的。
posted @
2012-04-24 13:56 王海光 閱讀(1868) |
評論 (0) |
編輯 收藏
修改左上角的圖標和任務欄里圖標
在對話框構造函數中
1 CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
2 : CDialog(CTestDlg::IDD, pParent)
3 {
4 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
5 }
改過后:
1 CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
2 : CDialog(CTestDlg::IDD, pParent)
3 {
4 m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
5 }
將最后的IDR_MAINFRAME改為自己的圖標即可,上面改為了IDI_ICON1,更改的圖標需要先導入或者添加進資源icon里,將默認的mfc圖標換成自己的。
修改生成EXE文件圖標
方法一:
要更改圖標,在resource.h中打開之后可以看到各個資源的ID值,一般mfc自動生成的IDR_MAINFRAME是128,自己添加的會大于128,順序后延,編譯時默認將ID最小的作為exe的圖標,所以只要我們將其改之就可以了,還是上面的對話框,將IDI_ICON1改為128,將IDR_MAINFRAME改為其他的大一點的數不能太大了,因為可能會有其他用處,然后重新rebuild,這時就可以看到exe圖標變成了自己的IDI_ICON1的圖標了。
方法二:
1、在程序res文件夾下,刪除MFC圖標文件,加入自己的圖標文件;
2、在圖標IDR_MAINFRAME的屬性對話框中,修改File name路徑為自己的圖標文件。
注:(1)一定要先刪除原文件,否則會把你的圖標文件覆蓋掉;
(2)完成后在資源視圖中可能發現還是原來的MFC圖標,但編譯后exe文件的圖標已經變成自己的了。
方法三:
在.rc文件中,可以修改默認圖標路徑來修改生成EXE文件圖標。
1 IDR_MAINFRAME ICON "res\\Test.ico"
修改后:
1 IDR_MAINFRAME ICON "res\\Test1.ico"
修改托盤中EXE文件圖標
可以用NOTIFYICONDATA來實現。
1 NOTIFYICONDATA _tnd;
2 _tnd.cbSize=sizeof(NOTIFYICONDATA);
3 _tnd.hWnd = this->GetSafeHwnd();
4 _tnd.uID = 0;
5 _tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
6 _tnd.dwInfoFlags = NIIF_INFO; // add an icon to a balloon ToolTip
7 _tnd.uTimeout = uTimeout;
8
9 CString sStatusMsg = szMsg;
10
11 if (“修改條件”)
12 {
13 _tnd.hIcon = theApp.LoadIcon(IDI_SUCCESSLOGIN);
14 }
posted @
2012-04-20 15:52 王海光 閱讀(12232) |
評論 (0) |
編輯 收藏