vector<CObj*>::iterator iterEnd = cObj.end();
vector<CObj*>::iterator iter = --iterEnd;
string strData = (*iter)->GetData();
[Container] 存有pointer的vector使用iterator取內容
使用方式如下
[Reg]登入後自動啟動程式
將需執行的程式之路徑寫到下列Registry Key底下即可
Current User:
\\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Local Machine:
\\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
一樣可以加入command line來使用。
KeyValue的Type為String,KeyValue名稱可自定
已知所支援之平台:
XP、Vista、Server2008
Current User:
\\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Local Machine:
\\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
一樣可以加入command line來使用。
KeyValue的Type為String,KeyValue名稱可自定
已知所支援之平台:
XP、Vista、Server2008
[Win]Mapping Disk的紀錄位置
XP、Server2008、Vista、Win7:
Key:HKEY_CURRENT_USER\Network
ValueType:String
ValueName:Remote Path
Key:HKEY_CURRENT_USER\Network
ValueType:String
ValueName:Remote Path
[Win]在SystemTray Icon上跳出Pop-up Menu
一開始先加入Menu的resource,然後輸入所要顯示的項目。
之後將對應的ID加入到MessageMap裡面去,並且也需要建立對應的操作行為。
這邊所需要用到的Function為ON_COMMAND()
例如:
Message Map
之後再宣告CMenu物件來使用。宣告位置在function或是header內都可以。
之後需要彈出menu時,僅需做下列步驟:
Maximum function
In Head file
In Cpp
不過目前跳出來的Pop-up menu在focus離開後並不會自行消失,且無法使用HotKey,所以這邊之後有時間再補上。
2009/12/08 - 註記
Pop-up menu不會消失的問題,只需在顯示pop-up menu之前多加個main form的SetForegroundWindow()就可以解決了。
之後將對應的ID加入到MessageMap裡面去,並且也需要建立對應的操作行為。
這邊所需要用到的Function為ON_COMMAND()
例如:
Message Map
BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
ON_COMMAND(ID_TRAYMENU_MAXIMIZE, OnTraymenuMax)
ON_COMMAND(ID_TRAYMENU_MINIMIZE, OnTraymenuMin)
ON_COMMAND(ID_TRAYMENU_CLOSE, OnTraymenuClose)
ON_COMMAND(ID_TRAYMENU_SHOWBALLOON, &CMDXMainDlg::OnTraymenuShowballoon)
END_MESSAGE_MAP()
之後再宣告CMenu物件來使用。宣告位置在function或是header內都可以。
之後需要彈出menu時,僅需做下列步驟:
this->m_pRClkMenu->LoadMenu(nMenuID);
this->m_pRClkMenu->GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, rect.left, rect.top, this, &rect);
this->m_pRClkMenu->Detach(); //這行也會讓menu消失
Maximum function
In Head file
afx_msg void OnTraymenuMax();
In Cpp
void CMainDlg::OnTraymenuMax()
{
this->ShowMainForm();
}
不過目前跳出來的Pop-up menu在focus離開後並不會自行消失,且無法使用HotKey,所以這邊之後有時間再補上。
2009/12/08 - 註記
Pop-up menu不會消失的問題,只需在顯示pop-up menu之前多加個main form的SetForegroundWindow()就可以解決了。
[MFC]比較安全的殺Modeless Dialog方法
在結束dialog之前,先在PostNcDestroy()內下PostMessage()或是SendMessage給()Parent Dialog來將pointer設成NULL。
之後再刪除this,這樣也比較不會發生modeless dialog內的destructor動作沒做完前,因Parent Dialog刪除modeless dialog而造成不定時的crash事件。
PostNcDestroy可以在IDDProperties裡面設定就可用了
Sample code
PostNcDestory
OnPostMessage
message map
in header file
in cpp
之後再刪除this,這樣也比較不會發生modeless dialog內的destructor動作沒做完前,因Parent Dialog刪除modeless dialog而造成不定時的crash事件。
PostNcDestroy可以在IDDProperties裡面設定就可用了
Sample code
PostNcDestory
void CMDXBatchJobManagerDlg::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
CDialog::PostNcDestroy();
::AfxGetMainWnd()->PostMessage(WM_MDLESSDLG_CLOSE);
//::AfxGetMainWnd()->SendMessage(WM_MDLESSDLG_CLOSE);
delete this;
}
OnPostMessage
LRESULT CMDXBatchJobManagerDlg::OnPostMessage(WPARAM wParam, LPARAM lParam)
{
m_pModelessDlg = NULL; //Set null. It will be delete by itself
return TRUE;
}
message map
in header file
#define WM_MDLESSDLG_CLOSE 10058 //Any unique value
in cpp
BEGIN_MESSAGE_MAP(CMDXBatchJobManagerDlg, CDialog)
ON_MESSAGE(WM_MDLESSDLG_CLOSE, PostNcDestroy)
END_MESSAGE_MAP()
Dialog隱藏後不在task tray顯示
從程式最小化至系統列的測試中發現即使程式最小化之後,還是會存在task tray內,這樣看起來是有點怪。因此需要在最小化時,另外去處理。
所需用到的Api為SetWindowLongPtr(MSDN上說明這樣在32與64平台間比較有相容性)
所需用到的Api為SetWindowLongPtr(MSDN上說明這樣在32與64平台間比較有相容性)
LONG_PTR SetWindowLongPtr(
HWND hWnd,
int nIndex,
LONG_PTR dwNewLong
);
以及GetWindowLongPtr參數部分可參考CreateWindowEX裡的dwExStyle。LONG_PTR GetWindowLongPtr(
HWND hWnd,
int nIndex
);
要不顯示於task tray的時候需用SetWindowLongPtr(hWnd, GWL_EXSTYLE,GetWindowLong(hWnd, GWL_EXSTYLE) & ~WS_EX_TOOLWINDOW);
如需還原時則可使用SetWindowLongPtr(hWnd, GWL_EXSTYLE,GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_TOOLWINDOW);
這邊所使用的參數WS_EX_TOOLWINDOW據MSDN的說法,可以讓ALT+TAB的時候也看不到程式,但測試的結果是失敗的,所以看來還需要其他方法才能達成吧。
(結果上面那段寫完之後,竟然成功的在ALT+TAB裡面看不到隱藏的程式,這可真是神奇阿XDD)
最後完成的code如下:LRESULT CMainDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
switch ( message )
{
case WM_USER: //NOTE:滑鼠移到上面就會送這個進來了
if ( lParam == WM_LBUTTONDBLCLK )
{
SetWindowLongPtr(hWnd, GWL_EXSTYLE,this->ShowWindow(SW_SHOW);
}else if ( lParam == WM_RBUTTONDOWN ) {
::AfxMessageBox("OnMessage_Right button");
}
break;
case WM_SYSCOMMAND: //NOTE:OnCancel會進來到這邊
if ( wParam == SC_MINIMIZE || wParam == SC_CLOSE)
{
if ( wParam == SC_CLOSE )
{
SetWindowLongPtr(hWnd, GWL_EXSTYLE, this->ShowWindow(SW_HIDE);
this->GotoSystemTray();
}
}
break;
}
return CDialog::WindowProc(message, wParam, lParam);
}
Reference:http://delphi.ktop.com.tw/board.php?cid=168&fid=912&tid=74287
程式最小化至系統工具列
所需要用到的API為Shell_NotifyIcon
如有需要針對滑鼠點擊System tray裡面的Icon反應的話,則需在uCallbackMessage給定回傳之訊息。
之後再於
Sample-縮到System Tray:
WinProc code:
Reference:http://blog.chinaunix.net/u2/67530/showart_603037.html
其所需傳入的結構為 NOTIFYICONDATABOOL Shell_NotifyIcon(
DWORD dwMessage,
PNOTIFYICONDATA lpdata
);
傳入的Message有NIM_ADD、
NIM_MODIFY、
NIM_DELETE、
NIM_SETFOCUS、
NIM_SETVERSION
typedef struct _NOTIFYICONDATAA{
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if (NTDDI_VERSION < NTDDI_WIN2K)
TCHAR szTip[64];
#endif
#if (NTDDI_VERSION >= NTDDI_WIN2K)
TCHAR szTip[128];
DWORD dwState;
DWORD dwStateMask;
TCHAR szInfo[256];
union{
UINT uTimeout;
UINT uVersion; // Used with Shell_NotifyIcon flag NIM_SETVERSION.
} DUMMYUNIONNAME;
TCHAR szInfoTitle[64];
DWORD dwInfoFlags;
#endif
#if (NTDDI_VERSION >= NTDDI_WINXP)
GUID guidItem;
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
HICON hBalloonIcon;
#endif
}
如有需要針對滑鼠點擊System tray裡面的Icon反應的話,則需在uCallbackMessage給定回傳之訊息。
之後再於
LRESULT CDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
裡面去接收所需要的資訊並作相對應的動作即可Sample-縮到System Tray:
bool CMainDlg::GotoSystemTray()
{
NOTIFYICONDATA NotifyIconData;
NotifyIconData.cbSize = sizeof (NOTIFYICONDATA);
NotifyIconData.hWnd = this->m_hWnd;
NotifyIconData.uID = IDD_MAINDLG;
NotifyIconData.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
NotifyIconData.hIcon = hIcon;
strcpy(NotifyIconData.szTip, "This is tip!!");
NotifyIconData.dwState = NIS_SHAREDICON;
strcpy(NotifyIconData.szInfo, "This is Info!!");
strcpy(NotifyIconData.szInfoTitle,"This is Info title!!");
NotifyIconData.dwInfoFlags = NIIF_INFO;
NotifyIconData.uCallbackMessage = WM_USER;
if ( !::Shell_NotifyIcon(NIM_ADD, &NotifyIconData) )
{
CString cstrDis;
cstrDis.Format("Err = %d", ::GetLastError());
::AfxMessageBox(cstrDis);
return false;
}
return true;
}
WinProc code:
LRESULT CMainDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
switch ( message )
{
case WM_USER: //NOTE:滑鼠移到上面就會送這個進來了
if ( lParam == WM_LBUTTONDBLCLK )
{
::AfxMessageBox("OnMessage_Left button");
}else if ( lParam == WM_RBUTTONDOWN ) {
::AfxMessageBox("OnMessage_Right button");
}
break;
case WM_SYSCOMMAND: //NOTE:OnCancel會進來到這邊
if ( wParam == SC_MINIMIZE || wParam == SC_CLOSE)
{::AfxMessageBox("OnSystem bar");
}
break;
}
return CDialog::WindowProc(message, wParam, lParam);
}
Reference:http://blog.chinaunix.net/u2/67530/showart_603037.html
FunctionPtr
在持有的class(即要給他人使用的class)的class內先宣告
之後有要用的人則先在自己的head file內加入
需要使用時則在cpp內做以下動作即可
上面內容目前還沒測過,僅用於memo用。
有誤還煩請指教。
class CClassName4PtrFunc
{
public:
typedef void (CClassName4PtrFunc::*PtrFuncName) (arg...);
public:
void FuncName(arg...);
};
之後有要用的人則先在自己的head file內加入
class CClassName4PtrFunc;
需要使用時則在cpp內做以下動作即可
#include "CClassName4PtrFunc.h"
void CIWantUsePtrFunc::UsePtrFunc(arg...)
{
CClassName4PtrFunc::PtrFuncName pPtrFunc;
(*pPtrFunc)(agr...);
}
上面內容目前還沒測過,僅用於memo用。
有誤還煩請指教。
[MFC]CListCtrl自動選擇一行
m_List.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
m_List.EnsureVisible(nIndex, FALSE);
不過使用上面方式後的選擇顯示是灰色的標記,並不是用滑鼠點選時的藍色。
如果需要選擇成藍色則如下:
m_List.SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
m_List.EnsureVisible(nIndex, FALSE);
m_List.SetFocus();
但是方法僅能用在按下按鈕的同時。
如有需要在另外的Thread中來做SetFocus(),則需使用SendMessage的方式來達成。
未指定大小的vector取址問題
目前使用vector來當做資料儲存用的array(這邊的資料都是用copy的方式存入vector),剛好又需要在thread內要去更新vector內的資料。
所以是利用取址的方式來將資料寫回原本使用的vector內。
此時發生只要有新資料進來的時候,原本取到的位置的值會被變更。
這邊是懷疑因為vector自動重新分配大小時,會將原本的就資料搬到新的記憶體位置。
所以原本參照的位置就變成沒有使用或是被別的變數使用了,所以導致只要有新資料進來,值就錯誤的問題。
後來重新於一開始就設定vector的capacity,之後下去運作後,先前的問題就都不見了,所以有以上之推論。
不過在map上並沒有發生類似的狀況,所以這邊還需要在詳查一下吧
所以是利用取址的方式來將資料寫回原本使用的vector內。
此時發生只要有新資料進來的時候,原本取到的位置的值會被變更。
這邊是懷疑因為vector自動重新分配大小時,會將原本的就資料搬到新的記憶體位置。
所以原本參照的位置就變成沒有使用或是被別的變數使用了,所以導致只要有新資料進來,值就錯誤的問題。
後來重新於一開始就設定vector的capacity,之後下去運作後,先前的問題就都不見了,所以有以上之推論。
不過在map上並沒有發生類似的狀況,所以這邊還需要在詳查一下吧
[WinAPI]FindWindow在Vista的奇異事件
話說最近嘗試透過PostMessage(HWND hwnd, LPARAM lpParam)要將一比資料從一個視窗程式傳到另一個視窗程式,這時候由於第一個程式的hWnd第二隻並不知道。所以這邊在第二個程式啟動的時候,就利用FindWindow來尋找第一個程式的hWnd。
在XP x32/x64以及Vista x64的平台上測試,都可以正正確確的找到第一個程式的hWnd。但是在"某台特定"的Vista x32上卻發生第二個程式永遠抓到一組固定的hWnd,即使是第一個程式有重開過。
這個現象就非常的不合理,因為每次視窗重新產生的時候,都會有不同的hWnd,所以這邊的FindWindow抓到了誰,那就不得而知了。所以這邊在做PostMessgae的時候,想當然,資料就永遠傳不到第一個程式了。
後來在網路上搜尋了一下,發現還有EnumWindow(WNDENUMPROC EnumProc, LPARAM lParam)可以用來取得所有視窗的hWnd。這個API還須透過一個Callback function來使用,就是EnumWindowProc(HWND hWnd, LPARAM lParam)。第二個參數看個人需求可選擇自行傳遞,這邊是因為要取得第一個程式的hWnd,所以這邊是傳入第一個程式的PID。
由於這邊是使用PID來比對,所以還需要透過GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId)來取得目前所列舉的視窗的PID。
之後就可以利用取得之hWnd來進行PostMessage了。
Callback的範例如下
EnumWindow使用範例如下
::EnumWindows(&EnumWindowsProc, (LPARAM)m_1stPID);
2009/Sep/30-Add
不過這種方法在遇到會換hWnd的Dialog下就會出問題(目前我遇到的是切換combo會造成hWnd的變更),所以最保險的還是用FindWindow會比較好。
不過還是要找比較安全的作法才行。
在XP x32/x64以及Vista x64的平台上測試,都可以正正確確的找到第一個程式的hWnd。但是在"某台特定"的Vista x32上卻發生第二個程式永遠抓到一組固定的hWnd,即使是第一個程式有重開過。
這個現象就非常的不合理,因為每次視窗重新產生的時候,都會有不同的hWnd,所以這邊的FindWindow抓到了誰,那就不得而知了。所以這邊在做PostMessgae的時候,想當然,資料就永遠傳不到第一個程式了。
後來在網路上搜尋了一下,發現還有EnumWindow(WNDENUMPROC EnumProc, LPARAM lParam)可以用來取得所有視窗的hWnd。這個API還須透過一個Callback function來使用,就是EnumWindowProc(HWND hWnd, LPARAM lParam)。第二個參數看個人需求可選擇自行傳遞,這邊是因為要取得第一個程式的hWnd,所以這邊是傳入第一個程式的PID。
由於這邊是使用PID來比對,所以還需要透過GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId)來取得目前所列舉的視窗的PID。
之後就可以利用取得之hWnd來進行PostMessage了。
Callback的範例如下
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
DWORD iPID = 0;
if ( GetWindowThreadProcessId(hwnd, &iPID) != NULL )
{
if ( iPID == (DWORD)lParam )
{
m_1sthWnd = hwnd;
return FALSE; //Find the PID and stop the callback function
}
}
return TRUE; //Continue the callback function
}
EnumWindow使用範例如下
::EnumWindows(&EnumWindowsProc, (LPARAM)m_1stPID);
2009/Sep/30-Add
不過這種方法在遇到會換hWnd的Dialog下就會出問題(目前我遇到的是切換combo會造成hWnd的變更),所以最保險的還是用FindWindow會比較好。
不過還是要找比較安全的作法才行。
[WinAPI]GetFileAttributes在Vista 64的%AppData%下無法正確判定是否為資料夾
一般在判定取得的路徑為檔案路徑或是資料夾路徑時,可透過GetFileAttributes來得知路徑的屬性。
這個方法在XP的版本下的時候,都可以正常取得到FILE_ATTRIBUTE_DIRECTORY,所以也可以正常的判定是否為資料夾。
然而在Vista上任意的路徑(如桌面、All User等)內的資料夾或是檔案路徑也都可以正常判定。
但是當路徑內轉指向%AppData%(c:\Users\CurUsrName\AppData\Roaming)的時候,如也是透過GetFileAttributes來取得路徑屬性的話,資料夾部分則會得到8208、檔案則會得到8224兩組值。
這兩組值並沒有在MSDN內被提供(http://msdn.microsoft.com/en-us/library/aa364944(VS.85).aspx)
所以後來經過Jacob的提醒,去檢查了這兩組值的binary值。
發現
8208 = 10 0000 0001 0000
8248 = 10 0000 0010 0000
這與
FILE_ATTRIBUTE_DIRECTORY = 00 0000 0001 0000
FILE_ATTRIBUTE_ARCHIVE = 00 0000 0010 0000
差了一個最高位的屬性。
所以這邊就根據Jacob的建議,在屬性判斷時,多做了BitMask來過濾掉其他不相干的屬性。
所以目前處理方式如下
至於最高位的那個bit是啥用途,那就等候M$大帝國公布啦XD
這個方法在XP的版本下的時候,都可以正常取得到FILE_ATTRIBUTE_DIRECTORY,所以也可以正常的判定是否為資料夾。
然而在Vista上任意的路徑(如桌面、All User等)內的資料夾或是檔案路徑也都可以正常判定。
但是當路徑內轉指向%AppData%(c:\Users\CurUsrName\AppData\Roaming)的時候,如也是透過GetFileAttributes來取得路徑屬性的話,資料夾部分則會得到8208、檔案則會得到8224兩組值。
這兩組值並沒有在MSDN內被提供(http://msdn.microsoft.com/en-us/library/aa364944(VS.85).aspx)
所以後來經過Jacob的提醒,去檢查了這兩組值的binary值。
發現
8208 = 10 0000 0001 0000
8248 = 10 0000 0010 0000
這與
FILE_ATTRIBUTE_DIRECTORY = 00 0000 0001 0000
FILE_ATTRIBUTE_ARCHIVE = 00 0000 0010 0000
差了一個最高位的屬性。
所以這邊就根據Jacob的建議,在屬性判斷時,多做了BitMask來過濾掉其他不相干的屬性。
所以目前處理方式如下
```cpp switch ( GetFileAttributes(szPath) & FILE_ATTRIBUTE_DIRECTORY ) { case FILE_ATTRIBUTE_DIRECTORY: return IS_DIR; case FILE_ATTRIBUTE_ARCHIVE: return IS_FILE; case INVALID_FILE_ATTRIBUTES: return IS_INVALID; default: return IS_UNKNOWN; } ```
至於最高位的那個bit是啥用途,那就等候M$大帝國公布啦XD
[Linux]malloc_usable_size使用注意事項
在windows下有個可以取得malloc的buffer size的函式-_msize()。
然而在linux底下是沒有相同的函式,所以後來又去網路上找到malloc_usable_size()這個函式。
雖然malloc_usable_size()可以取得到buffer size,不過呢,因為他是dependence on aligment。
所以取得的大小會等於或大於原本buffer size,如果要用來作比對或者是buffer大小計算的話,這邊就很容易出錯了。
至於替代方案目前還沒找到,所以有找到後再補上吧。
以下是參考連結:
http://www.slac.stanford.edu/comp/unix/package/rtems/doc/html/libc/libc.info.malloc.html
以下是部分文字節錄:
然而在linux底下是沒有相同的函式,所以後來又去網路上找到malloc_usable_size()這個函式。
雖然malloc_usable_size()可以取得到buffer size,不過呢,因為他是dependence on aligment。
所以取得的大小會等於或大於原本buffer size,如果要用來作比對或者是buffer大小計算的話,這邊就很容易出錯了。
至於替代方案目前還沒找到,所以有找到後再補上吧。
以下是參考連結:
http://www.slac.stanford.edu/comp/unix/package/rtems/doc/html/libc/libc.info.malloc.html
以下是部分文字節錄:
The `malloc_usable_size' function takes a pointer to a block
allocated by `malloc'. It returns the amount of space that is
available in the block. This may or may not be more than the size
requested from `malloc', due to alignment or minimum size constraints.
[VS神奇事件]pThread->InitInstance()發生crash事件
自從前述的libary link被修改事件被處理完成之後,再度又發生一個非常神奇的事件。
就是原本一個console application在run-time的時候crash了,crash的地方是在pThread->InitInstance()的地方。
在debug模式下發現這邊的pThread其實是一個NULL,所以會當掉也是很正常的。
然而這個pThread是放在AfxWinMain()底下,而AfxWinMain是在winmain.cpp裡面。
問題來了,一個console程式為何會需要用到winmain這個函式呢?
正在苦無解法的情況下,google到了這篇文章(http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/0ba47667-5067-4dc9-b667-87d40d7e2566)。
所以就照他的方法到了link底下的subsystem去檢查設定(Project->Properties->link->subsystem)。
結果,Bingo!!
M$的產品總是充滿驚喜阿,subsystem的設定竟然是winodws阿。
一整個無言,為何好端端的console程式會變成windows程式呢?
更何況3個月前他還是console阿,所以最後就把subsystem的設定調回console後,程式又可以正常運行了。
所以,M$讓我們的生活總是充滿驚喜阿!!!XD
就是原本一個console application在run-time的時候crash了,crash的地方是在pThread->InitInstance()的地方。
在debug模式下發現這邊的pThread其實是一個NULL,所以會當掉也是很正常的。
然而這個pThread是放在AfxWinMain()底下,而AfxWinMain是在winmain.cpp裡面。
問題來了,一個console程式為何會需要用到winmain這個函式呢?
正在苦無解法的情況下,google到了這篇文章(http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/0ba47667-5067-4dc9-b667-87d40d7e2566)。
所以就照他的方法到了link底下的subsystem去檢查設定(Project->Properties->link->subsystem)。
結果,Bingo!!
M$的產品總是充滿驚喜阿,subsystem的設定竟然是winodws阿。
一整個無言,為何好端端的console程式會變成windows程式呢?
更何況3個月前他還是console阿,所以最後就把subsystem的設定調回console後,程式又可以正常運行了。
所以,M$讓我們的生活總是充滿驚喜阿!!!XD
[VS神奇事件]Visual Studio無法開啟Find and Replace window-1
這個事件後來還是有發生,不過這次有經驗了,所以也就沒有在做solution的reset的動作XD
不過這次倒是有發現原因了。
主要Find and Replace window會跳的原因是因為只要這個視窗擋到被修改或是被搜尋的文字的時候,他會自動跳到不會遮住的地方,至於怎麼跳,那這邊要問M$,目前看不出他的patten。
而會跳到工作列下面是因為當初在做取代的時候,是用select的方式,所以等於整個被修改的文字都會被Find and Replace window給遮住了,而Find and Replace window為了不遮住那些被修改的文字,所以就跳到不會遮到的地方,也就是Text Editor外面。
不過後來在做測試的時候,Find and Replace window就沒有跳到工作列下面去了,所以這問題是要不小心使用的時候才會發生嗎?XD
PS.以上發生原因是經過數次實驗後所做的假設,不過解決方法倒是可行。至於實際原因就要問M$了XD
不過這次倒是有發現原因了。
主要Find and Replace window會跳的原因是因為只要這個視窗擋到被修改或是被搜尋的文字的時候,他會自動跳到不會遮住的地方,至於怎麼跳,那這邊要問M$,目前看不出他的patten。
而會跳到工作列下面是因為當初在做取代的時候,是用select的方式,所以等於整個被修改的文字都會被Find and Replace window給遮住了,而Find and Replace window為了不遮住那些被修改的文字,所以就跳到不會遮到的地方,也就是Text Editor外面。
不過後來在做測試的時候,Find and Replace window就沒有跳到工作列下面去了,所以這問題是要不小心使用的時候才會發生嗎?XD
PS.以上發生原因是經過數次實驗後所做的假設,不過解決方法倒是可行。至於實際原因就要問M$了XD
[VS神奇事件]LNK2019
最近把原本在windows上運作的程式porting到Linux上,在porting的過程中也沒有去改VS的專案設定。
在porting完成後想說在Windows上build看看原本的程式。結果卻在某個中間dll專案發生了LNK2019的問題,在整個檢查過程中發現所有原本要做dllexport的class全部都變成dllimport了,這時還以為是因為pre-processor key的部份沒有做設定,還特地把專案一個一個測試。
結果,問題並不是出在那邊,雖然VS的顯示上本來就有問題,但是那還不致於影響compiler的編譯。最後因為上網去找有關LNK2019的相關文獻發現,這問題在dll載入的動作中,是代表靜態連結有問題。
所以後來就去檢查專案的lib link,後來發現,果真,原本設定的那些lib link全部都不見了。
後來把原本該有的lib link都加上去後,complier就可以正常編譯了。
話說,這是VS的bug嗎?竟然把之前設定的資料都弄不見了?XD
就是因為相同的舊專案可以build,所以就沒懷疑到這邊。結果花了3天的時間在抓這問題,一整個殘念阿 -.-
在porting完成後想說在Windows上build看看原本的程式。結果卻在某個中間dll專案發生了LNK2019的問題,在整個檢查過程中發現所有原本要做dllexport的class全部都變成dllimport了,這時還以為是因為pre-processor key的部份沒有做設定,還特地把專案一個一個測試。
結果,問題並不是出在那邊,雖然VS的顯示上本來就有問題,但是那還不致於影響compiler的編譯。最後因為上網去找有關LNK2019的相關文獻發現,這問題在dll載入的動作中,是代表靜態連結有問題。
所以後來就去檢查專案的lib link,後來發現,果真,原本設定的那些lib link全部都不見了。
後來把原本該有的lib link都加上去後,complier就可以正常編譯了。
話說,這是VS的bug嗎?竟然把之前設定的資料都弄不見了?XD
就是因為相同的舊專案可以build,所以就沒懷疑到這邊。結果花了3天的時間在抓這問題,一整個殘念阿 -.-
[VS神奇事件]Visual Studio無法開啟Find and Replace window
最近因為需要動到大量(20個以上)的macro定義的變更,所以常用Replace的功能來把macro define以及 TEXT macro取代掉。
不過取代個幾次後,就會發生Find and Replace window無法叫出的狀況。
就是說不論是去介面上按Find and Replace window的按鈕或是用Hot key去呼叫,就是看不到Find and Replace window的蹤跡。
原本以為是因為設定檔壞掉了,所以就把設定檔做reset的動作,然後再把一些設定還原。
後來跟同事討論,才發覺不是window不見了,而是Visual Studio把window的座標改了。
我的狀況是window跑到工作列的後面了,所以才看不到。
這時候只要把工作列隱藏起來,就可以看到Find and Replace window的caption了。
再把Find and Replace window拉回可視範圍內就ok嚕。
所以如果有要把文字取代成空字串的時候,還是要多注意嚕。XD
不過據說,文字內含空白好像也會有同樣的問題,不過我沒遇到。
不過取代個幾次後,就會發生Find and Replace window無法叫出的狀況。
就是說不論是去介面上按Find and Replace window的按鈕或是用Hot key去呼叫,就是看不到Find and Replace window的蹤跡。
原本以為是因為設定檔壞掉了,所以就把設定檔做reset的動作,然後再把一些設定還原。
後來跟同事討論,才發覺不是window不見了,而是Visual Studio把window的座標改了。
我的狀況是window跑到工作列的後面了,所以才看不到。
這時候只要把工作列隱藏起來,就可以看到Find and Replace window的caption了。
再把Find and Replace window拉回可視範圍內就ok嚕。
所以如果有要把文字取代成空字串的時候,還是要多注意嚕。XD
不過據說,文字內含空白好像也會有同樣的問題,不過我沒遇到。
Subscribe to:
Posts (Atom)
Build docker image from multiple build contexts
Build docker image from multiple build contexts ...
-
參考資料: Input Input Manager 測試手把 :PS Analog gamepad Script語言:C# Unity 版本:3.4 Unity提供了3種輸入裝置可以使用,鍵盤、滑鼠、以及遊戲手把。 ...
-
寫法很簡單,就像下列寫法: if ( *szStr ) { .... } 因為*szStr == szStr[0],且char[]是以NULL-Terminate來判定字串是否結束,所以只要判定陣列的第一個值是不是為零,就可知道是否為空字串。 如需檢查是否為空字...