build DLL Release
copy curl\lib\DLL-Release\
libcurl_imp.lib
libcurl.dll
[Usage]
At project properties:
Linker:
General: Additional Library directories :.\curl\lib\x64
Input: Additional Dependencies: libcurl_imp.lib
then put libcurl.dll into exe folder.
2011年12月14日 星期三
2011年11月21日 星期一
LCID, LanguageID
LCID lcid = GetSystemDefaultLCID();
WORD LangID = LANGIDFROMLCID(lcid);
WORD PrimID = PRIMARYLANGID(LangID);
WORD SubID = SUBLANGID(LangID);
WORD LangID = LANGIDFROMLCID(lcid);
WORD PrimID = PRIMARYLANGID(LangID);
WORD SubID = SUBLANGID(LangID);
2011年11月17日 星期四
Stop CURL_EASY_PERFORM
Any of the callbacks (read/write/header/progress/debug/...) can be used to abort the transfer.
int Curlplus::writer(char *data, size_t size, size_t nmemb, void *lParam)
{
if (lParam == NULL)
return 0;
Curlplus* pThis = (Curlplus* )lParam;
int len = size*nmemb;
if(!pThis->m_bStopParse)
pThis->vParseData(data,len);
else
return CURLE_ABORTED_BY_CALLBACK;
}
int Curlplus::writer(char *data, size_t size, size_t nmemb, void *lParam)
{
if (lParam == NULL)
return 0;
Curlplus* pThis = (Curlplus* )lParam;
int len = size*nmemb;
if(!pThis->m_bStopParse)
pThis->vParseData(data,len);
else
return CURLE_ABORTED_BY_CALLBACK;
}
2011年9月6日 星期二
WaitForMultipleObjects
CClassView* pThis = (CClassView*) param;
pThis->m_bReadDone = false;
pThis->m_wndNodeCtrl.m_vctFileInfo.clear();
pThis->m_wndNodeCtrl.m_strEventInfo.clear();
HANDLE handles[2];
CWinThread * pThread[2];
pThread[0] = AfxBeginThread(thdReadDirectory,pThis);
pThread[1] = AfxBeginThread(CFileTreeList::thdGetEventFromDB, &(pThis->m_wndNodeCtrl));
for(int i=0;i<2;i++)
{
handles[i] = pThread[i]->m_hThread;
pThread[i]->m_bAutoDelete = false;
}
DWORD nRet = ::WaitForMultipleObjects(2, handles, true, INFINITE);
if(nRet == WAIT_OBJECT_0 )
{
pThis->m_wndNodeCtrl.vMatchEvent();
if(pThis->m_wndNodeCtrl.m_bEvent == true)
{
pThis->OnSelChangeDateCbobox();
pThis->m_wndNodeCtrl.UpdateWindow();
}
}
pThis->m_bReadDone = true;
delete pThread[0];
delete pThread[1];
return 0;
pThis->m_bReadDone = false;
pThis->m_wndNodeCtrl.m_vctFileInfo.clear();
pThis->m_wndNodeCtrl.m_strEventInfo.clear();
HANDLE handles[2];
CWinThread * pThread[2];
pThread[0] = AfxBeginThread(thdReadDirectory,pThis);
pThread[1] = AfxBeginThread(CFileTreeList::thdGetEventFromDB, &(pThis->m_wndNodeCtrl));
for(int i=0;i<2;i++)
{
handles[i] = pThread[i]->m_hThread;
pThread[i]->m_bAutoDelete = false;
}
DWORD nRet = ::WaitForMultipleObjects(2, handles, true, INFINITE);
if(nRet == WAIT_OBJECT_0 )
{
pThis->m_wndNodeCtrl.vMatchEvent();
if(pThis->m_wndNodeCtrl.m_bEvent == true)
{
pThis->OnSelChangeDateCbobox();
pThis->m_wndNodeCtrl.UpdateWindow();
}
}
pThis->m_bReadDone = true;
delete pThread[0];
delete pThread[1];
return 0;
2011年9月2日 星期五
transparent Dialog
Override OnCtlColor
HBRUSH CDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if(CTLCOLOR_DLG == nCtlColor)
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
return hbr;
}
HBRUSH CDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if(CTLCOLOR_DLG == nCtlColor)
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
return hbr;
}
2011年8月31日 星期三
LoadCursor
In App class
HCURSOR hCursor = LoadCursor(IDC_CURSOR_TVSET);
:SetCursor(((CApp*)AfxGetApp())->hCursor);
In other class:
HINSTANCE hInstant = AfxGetInstanceHandle();
HCURSOR hCursor = LoadCursor(hInstant,MAKEINTRESOURCE(IDC_CURSOR_TVSET));
::SetCursor(hCursor);
2011年8月4日 星期四
CString<-> TCHAR
TCHAR szMsg[100];
TCHAR *pszMsg;
CString csMsg;
pszMsg = new TCHAR[100];
memset(szMsg, 0, sizeof(szMsg) );
==================================
TCHAR -> CString
csMsg.Format(_T("%s"), szMsg);
CString ->TCHAR
_stprintf( szMsg, _T("%s"), csMsg.GetBuffer(csMsg.GetLength()));
//or _tcsncpy(szMsg, csMsg.GetBuffer(),_tcslen(csMsg));
pszMsg = csMsg.GetBuffer(csMsg.GetLength());
csMsg.ReleaseBuffer();
delete []pszMsg;
pszMsg = NULL;
TCHAR *pszMsg;
CString csMsg;
pszMsg = new TCHAR[100];
memset(szMsg, 0, sizeof(szMsg) );
==================================
TCHAR -> CString
csMsg.Format(_T("%s"), szMsg);
CString ->TCHAR
_stprintf( szMsg, _T("%s"), csMsg.GetBuffer(csMsg.GetLength()));
//or _tcsncpy(szMsg, csMsg.GetBuffer(),_tcslen(csMsg));
pszMsg = csMsg.GetBuffer(csMsg.GetLength());
csMsg.ReleaseBuffer();
delete []pszMsg;
pszMsg = NULL;
2011年6月28日 星期二
CreateWaitableTimer
1. Create
HANDLE hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
2. Set
LARGE_INTEGER liDueTime;
const int nTimerUnitsPerSecond=10*1000*1000; // the unit of timer is 100 nano seconds
// Set the event the first time 2 seconds after calling SetWaitableTimer
liDueTime.QuadPart= -(STARTTIMERAFTERSECOND * m_nTimerUnitsPerSecond );
int nTimerInterVal = 10;
SetWaitableTimer(hTimer,&liDueTime, (nTimerInterVal*nTimerUnitsPerSecond), NULL, NULL, false);
3. Use
HANDLE hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
2. Set
LARGE_INTEGER liDueTime;
const int nTimerUnitsPerSecond=10*1000*1000; // the unit of timer is 100 nano seconds
// Set the event the first time 2 seconds after calling SetWaitableTimer
liDueTime.QuadPart= -(STARTTIMERAFTERSECOND * m_nTimerUnitsPerSecond );
int nTimerInterVal = 10;
SetWaitableTimer(hTimer,&liDueTime, (nTimerInterVal*nTimerUnitsPerSecond), NULL, NULL, false);
3. Use
// Wait for the timer.
if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
printf("WaitForSingleObject failed (%d)\n", GetLastError());
else printf("Timer was signaled.\n");
Detect microphone VC++, waveInGetNumDevs
An easy way to detect the number of waveindevice using waveInGetNumDevs function
#include <Mmsystem.h>
#pragma comment( lib, "Winmm.lib" )
UINT nDevices = waveInGetNumDevs();
#include <Mmsystem.h>
#pragma comment( lib, "Winmm.lib" )
UINT nDevices = waveInGetNumDevs();
2011年6月14日 星期二
[InstallScript] MsiGetProperty, MsiSetProperty
There's a function to get value from Property in installscript
MsiGetProperty (hMSI, "ProductCode", szProductCode, numSize);
or set property
MsiSetProperty(hMSI, "NeedScheduleReboot", "1") ;
this example show how to set reboot after installation
MsiGetProperty (hMSI, "ProductCode", szProductCode, numSize);
or set property
MsiSetProperty(hMSI, "NeedScheduleReboot", "1") ;
this example show how to set reboot after installation
2011年6月13日 星期一
[Installshield] Access Installation Interview in InstallScript MSI project
There's no Installation Interview in project assist panel within a Installscript MSI project.
To modify which dialog boxes are displayed by modifying the OnFirstUIBefore event in the InstallScript view.
To modify which dialog boxes are displayed by modifying the OnFirstUIBefore event in the InstallScript view.
2011年6月2日 星期四
[InstallShield] installscript parse date time and RenameFile
This example code displays using GetSystemInfo to get system time, using StrGetTokens to parse date, time and RenameFile to rename files.
///////////////////////////////////////////////
// some defines are not showing here
function RenameDBFile(hMSI)
STRING szPath,szFileNameDB,szFileNameDBLog ,svResultDB,svResultLog,strDate,strTime,szRenameDB,szRenameDBLog;
INT nvDate,nvTime;
LIST listDate, listTime;
STRING svDdy, svDmn, svDyr, szDelim,szTimeStamp,svHr, svMin, svSec;
begin
GetSystemInfo(DATE, nvDate, strDate);
GetSystemInfo(TIME, nvTime, strTime);
listDate = ListCreate (STRINGLIST);
listTime = ListCreate (STRINGLIST);
StrGetTokens(listDate,strDate,"-");
ListGetFirstString(listDate,svDmn);
ListGetNextString(listDate,svDdy);
ListGetNextString(listDate,svDyr);
ListDestroy(listDate);
StrGetTokens(listTime,strTime,":");
ListGetFirstString(listTime,svHr);
ListGetNextString(listTime,svMin);
ListGetNextString(listTime,svSec);
ListDestroy(listTime);
szTimeStamp = "."+svDmn + "_" + svDdy + "_" + svDyr + "_" + svHr+ "_"+svMin+ "_"+svSec;
szPath = ProgramFilesFolder + DB_DATA_PATH;
szFileNameDB = DB_FILENAME;
szFileNameDBLog = DB_LOG_FILENAME;
szRenameDB = DB_FILENAME + szTimeStamp + ".bak";
szRenameDBLog = DB_LOG_FILENAME + szTimeStamp +".bak";
// Set SRCDIR and TARGETDIR for RenameFile
SRCDIR = szPath;
TARGETDIR = szPath;
if(FindFile(szPath, szFileNameDB, svResultDB) = 0 ) then
RenameFile(szFileNameDB,szRenameDB);
endif;
if(FindFile(szPath, szFileNameDBLog, svResultLog) = 0 ) then
RenameFile(szFileNameDBLog,szRenameDBLog);
endif;
end;
///////////////////////////////////////////////
// some defines are not showing here
function RenameDBFile(hMSI)
STRING szPath,szFileNameDB,szFileNameDBLog ,svResultDB,svResultLog,strDate,strTime,szRenameDB,szRenameDBLog;
INT nvDate,nvTime;
LIST listDate, listTime;
STRING svDdy, svDmn, svDyr, szDelim,szTimeStamp,svHr, svMin, svSec;
begin
GetSystemInfo(DATE, nvDate, strDate);
GetSystemInfo(TIME, nvTime, strTime);
listDate = ListCreate (STRINGLIST);
listTime = ListCreate (STRINGLIST);
StrGetTokens(listDate,strDate,"-");
ListGetFirstString(listDate,svDmn);
ListGetNextString(listDate,svDdy);
ListGetNextString(listDate,svDyr);
ListDestroy(listDate);
StrGetTokens(listTime,strTime,":");
ListGetFirstString(listTime,svHr);
ListGetNextString(listTime,svMin);
ListGetNextString(listTime,svSec);
ListDestroy(listTime);
szTimeStamp = "."+svDmn + "_" + svDdy + "_" + svDyr + "_" + svHr+ "_"+svMin+ "_"+svSec;
szPath = ProgramFilesFolder + DB_DATA_PATH;
szFileNameDB = DB_FILENAME;
szFileNameDBLog = DB_LOG_FILENAME;
szRenameDB = DB_FILENAME + szTimeStamp + ".bak";
szRenameDBLog = DB_LOG_FILENAME + szTimeStamp +".bak";
// Set SRCDIR and TARGETDIR for RenameFile
SRCDIR = szPath;
TARGETDIR = szPath;
if(FindFile(szPath, szFileNameDB, svResultDB) = 0 ) then
RenameFile(szFileNameDB,szRenameDB);
endif;
if(FindFile(szPath, szFileNameDBLog, svResultLog) = 0 ) then
RenameFile(szFileNameDBLog,szRenameDBLog);
endif;
end;
Dialog with SysLink control create fail
Using VS2008 SP1, adding a SysLink Control into a dailog and everything is fine in DEBUG mode.
When running in release mode.... something goes wrong, the dialog won't show up and return -1 fail code...
I traced this problem for a while i found it is the problem of SysLink
I saw a blog http://twigstechtips.blogspot.com/2010/03/c-dialogs-with-syslink-control-do-not.html
The main reason the Syslink causes the DialogBox() command to fail is because it requires unicode text support, starting from ComCtl32.dll 6.
add this code will solve the problem
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
2011年5月30日 星期一
32 bit application Registry location in x64 Windows
For 64 bit application in 64 bit Windows
HKEY_LOCAL_MACHINE\SOFTWARE\
For 32 bit application
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node
To access or store Registry by Win API, the API will redirect to the corresponding path
Also the uninstall registry of 32 bit application in win64 is located at
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{product GUID}
HKEY_LOCAL_MACHINE\SOFTWARE\
For 32 bit application
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node
To access or store Registry by Win API, the API will redirect to the corresponding path
Also the uninstall registry of 32 bit application in win64 is located at
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{product GUID}
2011年5月27日 星期五
ModifyMenu, DeleteMenu
CMenu MainMenu;
MainMenu.LoadMenu (IDR_MENU_NOTIFY);
MainMenu.ModifyMenuW(ID_STREAM_RESTART,MF_BYCOMMAND|MF_STRING,ID_STREAM_RESTART,_T("START"));
MainMenu.DeleteMenu(ID_STREAM_CLOSE,MF_BYCOMMAND);
MainMenu.LoadMenu (IDR_MENU_NOTIFY);
MainMenu.ModifyMenuW(ID_STREAM_RESTART,MF_BYCOMMAND|MF_STRING,ID_STREAM_RESTART,_T("START"));
MainMenu.DeleteMenu(ID_STREAM_CLOSE,MF_BYCOMMAND);
StartService ,StopService
To StartService or StopService, needs to use OpenSCManager and OpenService API to get SC_HANDLE
//============Stop Service============================
#include "Winsvc.h" // to use SC_HANDLE
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
TRACE(_T("KillService OpenSCManager failed"));
}
else
{
// open the service
SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
if (schService==0)
{
TRACE(_T("KillService OpenService failed"));
}
else
{
// call ControlService to kill the given service
SERVICE_STATUS status;
if(ControlService(schService, SERVICE_CONTROL_STOP, &status))
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
else
{
TRACE(_T("KillService ControlService failed"));
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
return FALSE;
//============Start Service===============
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
TRACE(_T("RunService OpenSCManager failed\r\n"));
}
else
{
// open the service
SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
if (schService == 0)
{
TRACE(_T("RunService OpenService failed"));
}
else
{
// call StartService to run the service
if(StartService(schService, 0, (const TCHAR**)NULL))
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
else
{
TRACE(_T("RunService StartService failed"));
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
return FALSE;
//============Stop Service============================
#include "Winsvc.h" // to use SC_HANDLE
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
TRACE(_T("KillService OpenSCManager failed"));
}
else
{
// open the service
SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
if (schService==0)
{
TRACE(_T("KillService OpenService failed"));
}
else
{
// call ControlService to kill the given service
SERVICE_STATUS status;
if(ControlService(schService, SERVICE_CONTROL_STOP, &status))
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
else
{
TRACE(_T("KillService ControlService failed"));
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
return FALSE;
//============Start Service===============
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
TRACE(_T("RunService OpenSCManager failed\r\n"));
}
else
{
// open the service
SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
if (schService == 0)
{
TRACE(_T("RunService OpenService failed"));
}
else
{
// call StartService to run the service
if(StartService(schService, 0, (const TCHAR**)NULL))
{
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
else
{
TRACE(_T("RunService StartService failed"));
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
return FALSE;
QueryServiceStatus
利用 OpenSCManager, OpenService 這兩個API可以查詢目前服務執行的狀態。
首先要#include "Winsvc.h" 才能使用SC_HANDLE等structure
bool bQueryResult = true;
// 利用OpenSCManager API 來得到 SC_HANDLE
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
TRACE(_T("RunService OpenSCManager failed\r\n"));
}
else
{
// open the service SC_HANDLE schService = OpenService( schSCManager,
pServiceName, // 這裡的ServiceName是執行檔的名稱(不含.exe),不是服務的顯示名稱
SERVICE_QUERY_STATUS); // 這裡表示執行查詢狀態
if (schService == 0)
{
TRACE(_T("RunService OpenService failed"));
}
else
{
SERVICE_STATUS ss; // 宣告一個SERVICE_STATUS structure
if(QueryServiceStatus(schService, &ss))
{
if(ss.dwCurrentState == SERVICE_RUNNING)
bQueryResult = true;
else
bQueryResult = false;
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
}
return bQueryResult;
首先要#include "Winsvc.h" 才能使用SC_HANDLE等structure
bool bQueryResult = true;
// 利用OpenSCManager API 來得到 SC_HANDLE
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager==0)
{
TRACE(_T("RunService OpenSCManager failed\r\n"));
}
else
{
// open the service SC_HANDLE schService = OpenService( schSCManager,
pServiceName, // 這裡的ServiceName是執行檔的名稱(不含.exe),不是服務的顯示名稱
SERVICE_QUERY_STATUS); // 這裡表示執行查詢狀態
if (schService == 0)
{
TRACE(_T("RunService OpenService failed"));
}
else
{
SERVICE_STATUS ss; // 宣告一個SERVICE_STATUS structure
if(QueryServiceStatus(schService, &ss))
{
if(ss.dwCurrentState == SERVICE_RUNNING)
bQueryResult = true;
else
bQueryResult = false;
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
}
return bQueryResult;
2011年5月26日 星期四
GetFileVersion
利用GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue這三個API來取得檔案的Version資訊
首先取得執行程式的位置
// get the app path
TCHAR apppath[MAX_PATH]={0};
GetModuleFileName(AfxGetInstanceHandle(),apppath,MAX_PATH-1);
CString csAppPath(apppath);
int nPos = csAppPath.ReverseFind('\\');
csAppPath = csAppPath.Left(nPos + 1);
csAppPath += _T("my.exe");
取得版本資訊
// get version
DWORD dwLen = 0;
TCHAR* lpData=NULL;
BOOL bSuccess = FALSE;
dwLen = GetFileVersionInfoSize(csAppPath, 0);
if (0 == dwLen)
{
return ;
}
lpData =new TCHAR [dwLen+1];
GetFileVersionInfo(csAppPath, 0, dwLen, lpData);
LPVOID lpBuffer = NULL;
UINT uLen = 0;
VerQueryValue(lpData,
_T("\\StringFileInfo\\040904b0\\FileVersion"),
//040904b0 can be found in resource view->version-> blockheader
/* properties for query 可以查詢的資訊
CompanyName
FileDescription
FileVersion
InternalName
LegalCopyright
OriginalFilename
ProductName
ProductVersion
Comments
LegalTrademarks
PrivateBuild
SpecialBuild
*/
&lpBuffer,
&uLen);
// lpBuffer存有查詢回來的資訊。
CString csVersion;
csVersion.Format(_T("%s"),(TCHAR*)lpBuffer);
m_csVersion += csVersion;
delete [] lpData;
// lpBuffer可以不用delete,因為他指向和lpData相同的記憶體空間
首先取得執行程式的位置
// get the app path
TCHAR apppath[MAX_PATH]={0};
GetModuleFileName(AfxGetInstanceHandle(),apppath,MAX_PATH-1);
CString csAppPath(apppath);
int nPos = csAppPath.ReverseFind('\\');
csAppPath = csAppPath.Left(nPos + 1);
csAppPath += _T("my.exe");
取得版本資訊
// get version
DWORD dwLen = 0;
TCHAR* lpData=NULL;
BOOL bSuccess = FALSE;
dwLen = GetFileVersionInfoSize(csAppPath, 0);
if (0 == dwLen)
{
return ;
}
lpData =new TCHAR [dwLen+1];
GetFileVersionInfo(csAppPath, 0, dwLen, lpData);
LPVOID lpBuffer = NULL;
UINT uLen = 0;
VerQueryValue(lpData,
_T("\\StringFileInfo\\040904b0\\FileVersion"),
//040904b0 can be found in resource view->version-> blockheader
/* properties for query 可以查詢的資訊
CompanyName
FileDescription
FileVersion
InternalName
LegalCopyright
OriginalFilename
ProductName
ProductVersion
Comments
LegalTrademarks
PrivateBuild
SpecialBuild
*/
&lpBuffer,
&uLen);
// lpBuffer存有查詢回來的資訊。
CString csVersion;
csVersion.Format(_T("%s"),(TCHAR*)lpBuffer);
m_csVersion += csVersion;
delete [] lpData;
// lpBuffer可以不用delete,因為他指向和lpData相同的記憶體空間
2011年5月12日 星期四
[轉錄] Static Class Members may not be Initialized in a Constructor
A common mistake is to initialize static class members inside the constructor body or a member-initialization list like this:
class File
{
private:
static bool locked;
private:
File();
//
};
File::File(): locked(false) {} //error, static initialization in a member initialization list
Although compilers flag these ill-formed initializations as errors, programmers often wonder why this is an error. Bear in mind that a constructor is called as many times as the number of objects created, whereas a static data member may be initialized only once because it is shared by all the class objects. Therefore, you should initialize static members outside the class, as in this example:
class File
{
private:
static bool locked;
private:
File() { /*..*/}
//
};
File::locked = false; //correct initialization of a non-const static member
Alternatively, for const static members of an integral type, the Standard now allows in-class initialization:
class Screen
{
private:
const static int pixels = 768*1024; //in-class initialization of const static integral types
public:
Screen() {/*..*/}
//
}; 原文網址: http://www.devx.com/tips/Tip/13148 2011年4月27日 星期三
HICON; LOADICON
LoadIcon使用方法
HICON hIcon = AfxGetApp()-> LoadIcon(nIconID);
HICON hIcon = LoadIcon(AfxGetApp()-> m_hInstance, MAKEINTRESOURCE(nIconID));
HICON hIcon = AfxGetApp()-> LoadIcon(nIconID);
HICON hIcon = LoadIcon(AfxGetApp()-> m_hInstance, MAKEINTRESOURCE(nIconID));
2011年4月15日 星期五
Modeless dialog
如果不想使用DoModal來呼叫建立dialog,可以使用modeless的dialog。
1.呼叫dialog的create,並傳入ID。
ex: CDialog dlg;
dlg.create(IDD_EXAMPLE);
2.在結束時呼叫DestroyWindow(),而不是EndDialog()
ref :http://msdn.microsoft.com/en-us/library/zhk0y9cw%28v=vs.80%29.aspx
1.呼叫dialog的create,並傳入ID。
ex: CDialog dlg;
dlg.create(IDD_EXAMPLE);
2.在結束時呼叫DestroyWindow(),而不是EndDialog()
ref :http://msdn.microsoft.com/en-us/library/zhk0y9cw%28v=vs.80%29.aspx
2011年4月14日 星期四
Add a new View in MFC MDI
首先加入一個繼承CView的MFC Class : CFlyAwayView;
1. @ Winapp.cpp InitInstance()
CMultiDocTemplate* pFlyAwayView;
pFlyAwayView = new CMultiDocTemplate(
IDR_EXTYPE,
RUNTIME_CLASS(CDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CFlyAwayView));
AddDocTemplate(pFlyAwayView);
pFlyAwayView->OpenDocumentFile(NULL);
//沒有這行View就沒有Active
2. @ MainFrame.cpp
在mainframe中調換view
OnMessageFunction():
CView* pView;
while (pView = MDIGetActive()->GetActiveView())
{
if (pView->IsKindOf( RUNTIME_CLASS(CFlyAwayView)))
{
AfxMessageBox(_T("hi"));
break;
}
MDINext();
MDIMaximize(pView);
}
1. @ Winapp.cpp InitInstance()
CMultiDocTemplate* pFlyAwayView;
pFlyAwayView = new CMultiDocTemplate(
IDR_EXTYPE,
RUNTIME_CLASS(CDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CFlyAwayView));
AddDocTemplate(pFlyAwayView);
pFlyAwayView->OpenDocumentFile(NULL);
//沒有這行View就沒有Active
2. @ MainFrame.cpp
在mainframe中調換view
OnMessageFunction():
CView* pView;
while (pView = MDIGetActive()->GetActiveView())
{
if (pView->IsKindOf( RUNTIME_CLASS(CFlyAwayView)))
{
AfxMessageBox(_T("hi"));
break;
}
MDINext();
MDIMaximize(pView);
}
2011年3月29日 星期二
Installshield Change Dialog Bitmap
To change Dialog Banner or Bitmap of Installshield dialog may reference this article
:http://www.flexerasoftware.com/webdocuments/PDF/DialogBitmaps.pdf
However, a simple way I used is just to override the default banner or bitmap ibd file
(1) find the default ibd path
[INSTALLSHIELD_PATH]\Redist\Language Independent\OS Independent
ex: C:\Program Files\InstallShield 10.5\Redist\Language Independent\OS Independent
2 ibd files in this folder
IsDialogBanner.ibd ---> this is for the banner on the top of dialog
IsDialogBitmap.ibd----> for bitmap left-side of dialog
(2) Rename 2 ibd files for backup and name the banner / bitmap image to .ibd
Rename IsDialogBanner.ibd to IsDialogBanner_old.ibd or IsDialogBanner.ibd.bak
Name the bitmap or jpg image you want to display to IsDialogBanner.ibd / IsDialogBitmap.ibd
(3) build the solution
[NOTE] the size of banner is 499x58 pixels and bitmap is 499x312 pixels
Remember that background color of right side of bitmap should other than black, or you can't see the texts.
:http://www.flexerasoftware.com/webdocuments/PDF/DialogBitmaps.pdf
However, a simple way I used is just to override the default banner or bitmap ibd file
(1) find the default ibd path
[INSTALLSHIELD_PATH]\Redist\Language Independent\OS Independent
ex: C:\Program Files\InstallShield 10.5\Redist\Language Independent\OS Independent
2 ibd files in this folder
IsDialogBanner.ibd ---> this is for the banner on the top of dialog
IsDialogBitmap.ibd----> for bitmap left-side of dialog
(2) Rename 2 ibd files for backup and name the banner / bitmap image to .ibd
Rename IsDialogBanner.ibd to IsDialogBanner_old.ibd or IsDialogBanner.ibd.bak
Name the bitmap or jpg image you want to display to IsDialogBanner.ibd / IsDialogBitmap.ibd
(3) build the solution
[NOTE] the size of banner is 499x58 pixels and bitmap is 499x312 pixels
Remember that background color of right side of bitmap should other than black, or you can't see the texts.
Installshield Restart after install/uninstall
在 Installation Designer' tab -> 'Behavior and Logic' -> 'Custom Actions and Sequences' -> 'Sequences' -> 'Installation' -> 'Execute' -> 'ScheduleReboot'
初始值是 ISSCHEDULEREBOOT
設定condition
(1) NOT REMOVE : 安裝完重開機
(2) REMOVE : Uninstall後restart
(3) NOT REMOVE AND REMOVE
如果不想看到重開機的提示
Go to 'Installation Designer' tab -> 'Behavior and Logic' -> 'Property Manager'
加入或修改
name : REBOOTPROMPT
value : Suppress
初始值是 ISSCHEDULEREBOOT
設定condition
(1) NOT REMOVE : 安裝完重開機
(2) REMOVE : Uninstall後restart
(3) NOT REMOVE AND REMOVE
如果不想看到重開機的提示
Go to 'Installation Designer' tab -> 'Behavior and Logic' -> 'Property Manager'
加入或修改
name : REBOOTPROMPT
value : Suppress
2011年3月28日 星期一
Installshield Combo box Property
在Installshield中的Dailog新增一個combo box
其中的property必須在"property Manager"中設為全域變數,即為大寫。
否則將視為local property
From Installshield help library:
Enter the name of a property that will be set when the end user enters a value into or selects one from this combo box. This property can be unique to this combo box; it need not be present in the Property Manager.
To set a default value for this combo box, make the property is a public property by giving it a name containing only uppercase letters (for example, COMBOPROPERTY), go to the Property Manager and add the public property, and then assign to it the value of the default selection (see Items, above).
其中的property必須在"property Manager"中設為全域變數,即為大寫。
否則將視為local property
From Installshield help library:
Enter the name of a property that will be set when the end user enters a value into or selects one from this combo box. This property can be unique to this combo box; it need not be present in the Property Manager.
To set a default value for this combo box, make the property is a public property by giving it a name containing only uppercase letters (for example, COMBOPROPERTY), go to the Property Manager and add the public property, and then assign to it the value of the default selection (see Items, above).
2011年3月25日 星期五
SendMessage , PostMessage
SendMessage 和 PostMessage可以將message傳送到一個特定的window
兩者的不同在於 SendMessage必須等到收方做完 PostMessage則是只送
首先要define一個ID 最好是不要重複
#define ID_CHANGE_BMP WM_USER+399
在送方的function
::PostMessage(GetParent()->m_hWnd,ID_CHANGE_BMP,(WPARAM)1,(LPARAM)NULL);
[NOTE]::PostMessage是Windows的function, PostMessage是MFC, 兩者的參數不同
WPARAM是 UINT_PTR。16 bits in Win 3.1, 32 in wind32
LPARAM LONG_PTR, 32
@收方
Message Map:
ON_MESSAGE(ID_CHANGE_BMP, OnChangeBMP)
LRESULT CIPCamTreeView::OnChangeBMP(WPARAM wParam, LPARAM lParam)
{
bChangeBmp(wParam);
return 0;
}
兩者的不同在於 SendMessage必須等到收方做完 PostMessage則是只送
首先要define一個ID 最好是不要重複
#define ID_CHANGE_BMP WM_USER+399
在送方的function
::PostMessage(GetParent()->m_hWnd,ID_CHANGE_BMP,(WPARAM)1,(LPARAM)NULL);
[NOTE]::PostMessage是Windows的function, PostMessage是MFC, 兩者的參數不同
WPARAM是 UINT_PTR。16 bits in Win 3.1, 32 in wind32
LPARAM LONG_PTR, 32
@收方
Message Map:
ON_MESSAGE(ID_CHANGE_BMP, OnChangeBMP)
LRESULT CIPCamTreeView::OnChangeBMP(WPARAM wParam, LPARAM lParam)
{
bChangeBmp(wParam);
return 0;
}
2011年3月21日 星期一
CToolTipCtrl
CToolTipCtrl *m_pOSDToolTip;
OnCreate()
{
if(!m_pOSDToolTip)
{
m_pOSDToolTip= new CToolTipCtrl();
m_pOSDToolTip->Create(this);
m_pOSDToolTip->AddTool(m_pFixRatio,_T("Fix Ratio")); // CBitmapButton * m_pFixRatio
m_pOSDToolTip->AddTool(m_pSnapShot,_T("Snapshot"));
m_pOSDToolTip->Activate(TRUE);
}
}
PreTranslateMessage(MSG* pMsg)
{
if(m_bDisplayOSD)
m_pOSDToolTip->RelayEvent(pMsg);
return CStatic::PreTranslateMessage(pMsg);
}
OnCreate()
{
if(!m_pOSDToolTip)
{
m_pOSDToolTip= new CToolTipCtrl();
m_pOSDToolTip->Create(this);
m_pOSDToolTip->AddTool(m_pFixRatio,_T("Fix Ratio")); // CBitmapButton * m_pFixRatio
m_pOSDToolTip->AddTool(m_pSnapShot,_T("Snapshot"));
m_pOSDToolTip->Activate(TRUE);
}
}
PreTranslateMessage(MSG* pMsg)
{
if(m_bDisplayOSD)
m_pOSDToolTip->RelayEvent(pMsg);
return CStatic::PreTranslateMessage(pMsg);
}
2011年3月16日 星期三
Change CStatic Font color
Create a CStatic control
RECT rect;
RECT rcParent;
GetClientRect(&rcParent);
rect.left = rcParent.left;
rect.right = rcParent.right - nBtnWidth;
rect.top = rcParent.top ;
rect.bottom = rcParent.top + nOSDHeight;
if(! m_pCaption)
{
m_pCaption = new CStatic();
bRet |= m_pCaption->Create(NULL, WS_CHILD|WS_VISIBLE|SS_NOTIFY, rect, this , IDC_CAPTIONBAR);//
if(csCameraName.IsEmpty()) csCameraName = _T("Untitled");
m_pCaption->SetWindowTextW(csCameraName);
/*CFont * font = new CFont;
font->CreateFontW(22,0,0,0,FW_SEMIBOLD,false,false,0,CHINESEBIG5_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH&FF_SWISS,_T("Arial"));
m_pCaption->SetFont(font);*/
}
{
HBRUSH hbr = CStatic::OnCtlColor(pDC, pWnd, nCtlColor);
COLORREF textColor = RGB(255,255,255);
COLORREF bkColor = RGB(0,0,0);
if(nCtlColor == CTLCOLOR_STATIC) //
{
pDC->SetTextColor(textColor);
pDC->SetBkColor(bkColor); // 這裡的background color只限於text周圍, 並不是CStatic所create出來的整個rectangle
hbr = CreateSolidBrush(bkColor); // 這樣才會填滿整個retangle
}
return hbr;
其中
或者可以指定要改哪個ID
if(pWnd->GetDlgCtrlID() ==IDC_CAPTIONBAR)
{
pDC->SetTextColor(textColor);
pDC->SetBkColor(bkColor);
}
return hbr;
}
RECT rect;
RECT rcParent;
GetClientRect(&rcParent);
rect.left = rcParent.left;
rect.right = rcParent.right - nBtnWidth;
rect.top = rcParent.top ;
rect.bottom = rcParent.top + nOSDHeight;
if(! m_pCaption)
{
m_pCaption = new CStatic();
bRet |= m_pCaption->Create(NULL, WS_CHILD|WS_VISIBLE|SS_NOTIFY, rect, this , IDC_CAPTIONBAR);//
if(csCameraName.IsEmpty()) csCameraName = _T("Untitled");
m_pCaption->SetWindowTextW(csCameraName);
/*CFont * font = new CFont;
font->CreateFontW(22,0,0,0,FW_SEMIBOLD,false,false,0,CHINESEBIG5_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH&FF_SWISS,_T("Arial"));
m_pCaption->SetFont(font);*/
}
Override WM_CTLCOLOR message
HBRUSH CVideo::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor){
HBRUSH hbr = CStatic::OnCtlColor(pDC, pWnd, nCtlColor);
COLORREF textColor = RGB(255,255,255);
COLORREF bkColor = RGB(0,0,0);
if(nCtlColor == CTLCOLOR_STATIC) //
{
pDC->SetTextColor(textColor);
pDC->SetBkColor(bkColor); // 這裡的background color只限於text周圍, 並不是CStatic所create出來的整個rectangle
hbr = CreateSolidBrush(bkColor); // 這樣才會填滿整個retangle
}
return hbr;
其中
- CTLCOLOR_BTN Button control
- CTLCOLOR_DLG Dialog box
- CTLCOLOR_EDIT Edit control
- CTLCOLOR_LISTBOX List-box control
- CTLCOLOR_MSGBOX Message box
- CTLCOLOR_SCROLLBAR Scroll-bar control
- CTLCOLOR_STATIC Static control
或者可以指定要改哪個ID
if(pWnd->GetDlgCtrlID() ==IDC_CAPTIONBAR)
{
pDC->SetTextColor(textColor);
pDC->SetBkColor(bkColor);
}
return hbr;
}
OnEraseBkgnd
OnEraseBkgnd()
{
pDC->SetBkColor(BKCOLOR);//BKCOLOR
CRect rect;
GetClientRect(rect);
CBrush bkColor(RGB(190,190,190));
pDC->FillRect(&rect,&bkColor);
}
Override :WM_ERASEBKGND message
利用FillRect函式在視窗大小改變時 將background重畫。
{
pDC->SetBkColor(BKCOLOR);//BKCOLOR
CRect rect;
GetClientRect(rect);
CBrush bkColor(RGB(190,190,190));
pDC->FillRect(&rect,&bkColor);
}
Override :WM_ERASEBKGND message
利用FillRect函式在視窗大小改變時 將background重畫。
2011年3月11日 星期五
[MFC] Get Applcation file name
TCHAR szPath[MAX_PATH];
if( !GetModuleFileName(NULL, szPath, MAX_PATH ))
{
printf("GetModuleFileName failed (%d)\n", GetLastError());
return _T("");
}
CString strPath(szPath);
int nPos = strPath.ReverseFind('\\');
strPath = strPath.Left(nPos + 1);
或者
TCHAR szPathName[MAX_PATH] = { 0 };
TCHAR szDrive[_MAX_DRIVE] = { 0 };
TCHAR szDir[_MAX_DIR] = { 0 };
TCHAR szFname[_MAX_FNAME] = { 0 };
TCHAR szExt[_MAX_EXT] = { 0 };
(void)::GetModuleFileName( NULL, szPathName, MAX_PATH );
_splitpath( szPathName, szDrive, szDir, szFname, szExt );
if( !GetModuleFileName(NULL, szPath, MAX_PATH ))
{
printf("GetModuleFileName failed (%d)\n", GetLastError());
return _T("");
}
CString strPath(szPath);
int nPos = strPath.ReverseFind('\\');
strPath = strPath.Left(nPos + 1);
或者
TCHAR szPathName[MAX_PATH] = { 0 };
TCHAR szDrive[_MAX_DRIVE] = { 0 };
TCHAR szDir[_MAX_DIR] = { 0 };
TCHAR szFname[_MAX_FNAME] = { 0 };
TCHAR szExt[_MAX_EXT] = { 0 };
(void)::GetModuleFileName( NULL, szPathName, MAX_PATH );
_splitpath( szPathName, szDrive, szDir, szFname, szExt );
2011年2月21日 星期一
將 data(struct) 寫到Registry。
1. Set
HKEY hkFolder;
DWORD dwDisposition = REG_CREATED_NEW_KEY;
if(!m_vctNode.empty()) m_vctNode.clear();
if (ERROR_SUCCESS == ::RegCreateKeyEx(HKEY_CURRENT_USER, REGISTSUBFOLDER, NULL, _T("NODEITEM"),
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkFolder, &dwDisposition))
{
DWORD nSize = vctpNode.size();
NODEITEM * pNode = new NODEITEM[nSize];
for(int i=0;i<vctpNode.size();i++)
{
m_vctNode.push_back(*(vctpNode[i]));
pNode[i] = (*(vctpNode[i]));
}
RegSetValueEx(hkFolder, _T("NODEITEM"), NULL, REG_BINARY, (BYTE*) pNode, nSize * sizeof(NODEITEM));
delete [] pNode;
}
RegCloseKey(hkFolder);
2. Get
vGetAppCacheFolder();
HKEY hkFolder;
DWORD cbData = 0;
DWORD nType = REG_BINARY;
bool bResult = false;
NODEITEM *pNode = NULL;
LONG nRet1 = RegOpenKey(HKEY_CURRENT_USER, REGISTSUBFOLDER, &hkFolder);
cbData = 0;
LONG nRet2 = RegQueryValueEx(hkFolder, _T("NODEITEM"), NULL, &nType, (BYTE*)pNode, &cbData);
DWORD nApplySize = cbData/sizeof(NODEITEM);
pNode = new NODEITEM[nApplySize];
memset(pNode, 0, nApplySize);
nRet2 = RegQueryValueEx(hkFolder, _T("NODEITEM"), NULL, &nType, (BYTE*)pNode, &cbData);
if ( nRet1 == ERROR_SUCCESS && nRet2 == ERROR_SUCCESS )
{
m_vctNode.clear();
int nSize = cbData/sizeof(NODEITEM);
for (int ci=0; ci < nSize; ci++)
{
try{
m_vctNode.push_back((pNode[ci]));
}
catch(exception* e){
delete e;
m_vctNode.clear();
delete [] pNode;
return false;
}
}
bResult = true;
}else
{
FORMATMESSAGE(nRet2);
}
try
{
delete [] pNode;
}catch(exception* e)
{
m_vctNode.clear();
delete e;
}
RegCloseKey(hkFolder);
return bResult;
HKEY hkFolder;
DWORD dwDisposition = REG_CREATED_NEW_KEY;
if(!m_vctNode.empty()) m_vctNode.clear();
if (ERROR_SUCCESS == ::RegCreateKeyEx(HKEY_CURRENT_USER, REGISTSUBFOLDER, NULL, _T("NODEITEM"),
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkFolder, &dwDisposition))
{
DWORD nSize = vctpNode.size();
NODEITEM * pNode = new NODEITEM[nSize];
for(int i=0;i<vctpNode.size();i++)
{
m_vctNode.push_back(*(vctpNode[i]));
pNode[i] = (*(vctpNode[i]));
}
RegSetValueEx(hkFolder, _T("NODEITEM"), NULL, REG_BINARY, (BYTE*) pNode, nSize * sizeof(NODEITEM));
delete [] pNode;
}
RegCloseKey(hkFolder);
2. Get
vGetAppCacheFolder();
HKEY hkFolder;
DWORD cbData = 0;
DWORD nType = REG_BINARY;
bool bResult = false;
NODEITEM *pNode = NULL;
LONG nRet1 = RegOpenKey(HKEY_CURRENT_USER, REGISTSUBFOLDER, &hkFolder);
cbData = 0;
LONG nRet2 = RegQueryValueEx(hkFolder, _T("NODEITEM"), NULL, &nType, (BYTE*)pNode, &cbData);
DWORD nApplySize = cbData/sizeof(NODEITEM);
pNode = new NODEITEM[nApplySize];
memset(pNode, 0, nApplySize);
nRet2 = RegQueryValueEx(hkFolder, _T("NODEITEM"), NULL, &nType, (BYTE*)pNode, &cbData);
if ( nRet1 == ERROR_SUCCESS && nRet2 == ERROR_SUCCESS )
{
m_vctNode.clear();
int nSize = cbData/sizeof(NODEITEM);
for (int ci=0; ci < nSize; ci++)
{
try{
m_vctNode.push_back((pNode[ci]));
}
catch(exception* e){
delete e;
m_vctNode.clear();
delete [] pNode;
return false;
}
}
bResult = true;
}else
{
FORMATMESSAGE(nRet2);
}
try
{
delete [] pNode;
}catch(exception* e)
{
m_vctNode.clear();
delete e;
}
RegCloseKey(hkFolder);
return bResult;
2011年2月17日 星期四
vector::erase和iterator的問題
vector 在erase後,原本的iterator會失效 (被移除了)
所以在使用for-loop + erase要注意
std::vector::erase()會回傳一個有效的iterator
example::
std::vector<int> myVector;
std::vector<int>::iterator it;
for(it = myVector.begin(); it !=myVector.end();)
{
if(*it != 1)
it = myVector.erase(it);
else
++it;
}
所以在使用for-loop + erase要注意
std::vector::erase()會回傳一個有效的iterator
example::
std::vector<int> myVector;
std::vector<int>::iterator it;
for(it = myVector.begin(); it !=myVector.end();)
{
if(*it != 1)
it = myVector.erase(it);
else
++it;
}
2011年2月16日 星期三
How To Check If Computer Is Running A 32 Bit or 64 Bit Operating System in Registry
1.HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
Identifier REG_SZ x86 Family 6 Model 14 Stepping 12
Platform ID REG_DWORD 0x00000020(32)
2. HKLM\SYSTEM\CurrentCongtrolSet\Control\Session Manager\Envirornment
PROCESSOR_ARCHITECTURE REG_SZ x86
3.HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
BuildLabEx REG_SZ 7600.16695.x86fre.win7_gdr.101026-1503
Identifier REG_SZ x86 Family 6 Model 14 Stepping 12
Platform ID REG_DWORD 0x00000020(32)
2. HKLM\SYSTEM\CurrentCongtrolSet\Control\Session Manager\Envirornment
PROCESSOR_ARCHITECTURE REG_SZ x86
3.HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
BuildLabEx REG_SZ 7600.16695.x86fre.win7_gdr.101026-1503
2011年2月14日 星期一
CPen
CPen pen(PS_SOLID,2,RGB(192,192,192));
CPen *oldPen;
oldPen = pDC->SelectObject(&pen1);
pDC->MoveTo(10,10);\\ 起點
pDC->LineTo(200,20);\\ 線的終點
pDC->SelectObject(oldPen);
example:
for(int i=0;i<5;i++)
{
CPen* pPen = &Pen;
CPen *pOldPen = pDC->SelectObject( pPen );
pDC->MoveTo(0,row);
pDC->LineTo(nWidth,row);
pDC->SelectObject( &pOldPen );
row+=20;
}
CPen *oldPen;
oldPen = pDC->SelectObject(&pen1);
pDC->MoveTo(10,10);\\ 起點
pDC->LineTo(200,20);\\ 線的終點
pDC->SelectObject(oldPen);
example:
for(int i=0;i<5;i++)
{
CPen* pPen = &Pen;
CPen *pOldPen = pDC->SelectObject( pPen );
pDC->MoveTo(0,row);
pDC->LineTo(nWidth,row);
pDC->SelectObject( &pOldPen );
row+=20;
}
2011年2月9日 星期三
取消CDockablePane的Close button (修改CDockablePane的風格)
1. OnCreate
the AFX_DEFAULT_DOCKING_PANE_STYLE defined is
static const DWORD AFX_DEFAULT_DOCKING_PANE_STYLE = AFX_CBRS_FLOAT | AFX_CBRS_CLOSE | AFX_CBRS_RESIZE | AFX_CBRS_AUTOHIDE;
把AFX_CBRS_CLOSE移除即可
m_wndClassView.Create( strFileViewWnd, this, CRect( 0, 0, 200, 200 ), TRUE, ID_PANE_FILEVIEW_WND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI, AFX_CBRS_REGULAR_TABS, AFX_CBRS_FLOAT | AFX_CBRS_RESIZE | AFX_CBRS_AUTOHIDE ) ;
2. GetControlBarStyle() and SetControlBarStyle( dwStyle )
DWORD dwStyle = m_wndClassView.GetControlBarStyle();
dwStyle &= ~( AFX_CBRS_CLOSE | AFX_CBRS_RESIZE | AFX_CBRS_FLOAT| AFX_CBRS_AUTOHIDE);
m_wndClassView.SetControlBarStyle( dwStyle );
the AFX_DEFAULT_DOCKING_PANE_STYLE defined is
static const DWORD AFX_DEFAULT_DOCKING_PANE_STYLE = AFX_CBRS_FLOAT | AFX_CBRS_CLOSE | AFX_CBRS_RESIZE | AFX_CBRS_AUTOHIDE;
把AFX_CBRS_CLOSE移除即可
m_wndClassView.Create( strFileViewWnd, this, CRect( 0, 0, 200, 200 ), TRUE, ID_PANE_FILEVIEW_WND, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI, AFX_CBRS_REGULAR_TABS, AFX_CBRS_FLOAT | AFX_CBRS_RESIZE | AFX_CBRS_AUTOHIDE ) ;
2. GetControlBarStyle() and SetControlBarStyle( dwStyle )
DWORD dwStyle = m_wndClassView.GetControlBarStyle();
dwStyle &= ~( AFX_CBRS_CLOSE | AFX_CBRS_RESIZE | AFX_CBRS_FLOAT| AFX_CBRS_AUTOHIDE);
m_wndClassView.SetControlBarStyle( dwStyle );
2011年2月8日 星期二
CTime CString 互轉
CString -> CTime
TCHAR *tcValidTimeFrom, *tcValidTimeTo;
int iHour, iMinute,iSecond;
tcValidTimeFrom = (TCHAR*)(LPCTSTR) csValidTimeFrom; _stscanf(tcValidTimeFrom, _T("%d:%d:%d"), &iHour, &iMinute, &iSecond);
CTime ctimeValidFrom(1970,1,1,iHour,iMinute,iSecond);
CTime -> CString
CTime time;
CString csDate;
CString csDate = time.Format(_T("%Y\%m\%d"));
TCHAR *tcValidTimeFrom, *tcValidTimeTo;
int iHour, iMinute,iSecond;
tcValidTimeFrom = (TCHAR*)(LPCTSTR) csValidTimeFrom; _stscanf(tcValidTimeFrom, _T("%d:%d:%d"), &iHour, &iMinute, &iSecond);
CTime ctimeValidFrom(1970,1,1,iHour,iMinute,iSecond);
CTime -> CString
CTime time;
CString csDate;
CString csDate = time.Format(_T("%Y\%m\%d"));
訂閱:
意見 (Atom)