最新:
PictureDlg:Ver.2.40,
CImgWnd2:Ver.6.20,
MyLapack:Ver.1.20,
CGraphWnd:Ver.3.60,
CGlWnd:Ver.6.40,
C2DFFT:Ver.2.30,
CU2DFFT:Ver.2.00,
CCPUTimer:Ver.1.00,
- ループ処理
MSG message;
while(1){
//処理
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)){
//ループ中のマウスメッセージ処理
::TranslateMessage(&message);
::DispatchMessage(&message);
}
}
- 時間測定
#include "mmsystem.h"
#pragma comment(lib,"winmm.lib")
DWORD time1, time2;
time1=timeGetTime();
//処理
time2=timeGetTime();
TRACE("time1=%d", time2-time1);
- 時間測定2
timeGetTimeは高精度な時間測定ができない.
(私の場合初回は0msか15msになってしまう).
CPUカウンタを用いた高精度時間測定法を記す。
LARGE_INTEGER CPUFreq;
LARGE_INTEGER StartTime;
LARGE_INTEGER StopTime;
DWORD time:
QueryPerformanceFrequency(&CPUFreq);
QueryPerformanceCounter(&StartTime);
//処理
QueryPerformanceCounter(&StopTime);
time = (StopTime.QuadPart-StartTime.QuadPart)*1000000/CPUFreq.QuadPart; //[us]単位
- タイマー処理
//ヘッダ
#define MY_TIMER (WM_USER + 0x0020)
afx_msg void OnTimer(UINT nIDEvent);
DECLARE_MESSAGE_MAP()
//.cpp
BEGIN_MESSAGE_MAP(CxxxWnd, CGlWnd)
ON_WM_TIMER()
END_MESSAGE_MAP()
void CGLClassDlg::OnTimer(UINT nIDEvent)
{
switch(nIDEvent){
case MY_TIMER:
break;
}
}
//タイマセット
SetTimer(MY_TIMER,100,0);//100msごと
//タイマ停止
KillTimer(MY_TIMER);
- マルチメディアタイマ timeSetEvent
ウィンドウメッセージタイマだと,
メインスレッドが重くてキューを見に行けないことがある.
マルチメディアタイマを用いると、ほぼ確実にコールすることができる.
ただし、スレッドが別に切られるので、
デバイスコンテキスト等の管理に気を使う.
//宣言
MMRESULT g_mmresult;
void CALLBACK TimeCallback(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
//タイマ呼び出し
timeBeginPeriod(1);
g_mmresult = timeSetEvent(1000/FRATE, 1, TimeCallback, 0, TIME_PERIODIC);// TIME_ONESHOT:1回だけ, TIME_PERIODIC:繰り返し
//コールバック関数
void CALLBACK TimeCallback(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
static int init=0;
if(init==0){
g_pWnd->GLInitT();
init = 1;
}
if(g_DrawLR){
g_DrawLR=0;
g_pWnd->DrawLeft();
} else {
g_DrawLR=1;
g_pWnd->DrawRight();
}
}
//タイマ終了処理
timeKillEvent(g_mmresult);
timeEndPeriod(1);
g_mmresult=NULL;
- ウィンドウメッセージ処理
//ヘッダ
#define WM_MY_MSG (WM_USER + 0x0100)
#define WM_WPARM1 (0x0001)
afx_msg LRESULT OnCallBack(WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
//実体
BEGIN_MESSAGE_MAP(CxxxWnd, CGlWnd)
ON_MESSAGE( WM_MY_MSG, OnCallBack)
END_MESSAGE_MAP()
LRESULT CxxxWnd::OnCallBack(WPARAM wParam, LPARAM lParam)
{
switch(wParam){
case MY_WPARM1:
return (LRESULT)0;
}
}
//呼び出し側
PostMessage( hWnd, WM_MY_MSG, MY_WPARM1, lParam);
- キー入力処理
//ヘッダ
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) ;
DECLARE_MESSAGE_MAP()
//実体
BEGIN_MESSAGE_MAP(CxxxWnd, CGlWnd)
ON_WM_KEYDOWN(WM_KEYDOWN, OnKeyDown)
END_MESSAGE_MAP()
void CxxxWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if(nChar=='Q'){
CWnd *pWnd;
pWnd=pWnd->FromHandle(m_hStopWnd);
if(pWnd) pWnd->SendMessage(COLIOWND_MSG_STOP,0,0);
}
}
- キー入力処理(その2)
ダイアログなどはキー入力がウィンドウに食われて上記の方法は使えない.
PreTranslateMessageをオーバーライドする.
BOOL CxxxDlg::PreTranslateMessage(MSG *pMsg)
{
if(pMsg->message == WM_KEYDOWN){
unsined char nChar = (unsigned char)pMsg->wParam;
switch(nChar){
....
}
}
return CDialog::PreTranslateMessage(pMsg);
}
- マウスホイール
//ヘッダ.h
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
//実体.cpp
BEGIN_MESSAGE_MAP(CDraw3DDlg, CDialog)
ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()
BOOL CDraw3DDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。
g_GlWnd.SetDeltaModelDist((double)zDelta/WHEEL_DELTA/10.0);
return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}
- ワーカースレッド処理
//スレッド開始
CWinThread *pThread = AfxBeginThread( ThreadFunc, Param, THREAD_PRIORITY_NORMAL);
//実際スレッドの定義
UINT ThreadFunc(LPVOID pParam)
{
//スレッド処理
return 0;
}
メインループからスレッドを止める、再開する
CWinThread::Suspend()
CWinThread::ResumeThread()
- ちらつきを抑える(その1)
WM_ERASEBKGNDにより背景が描画された後OnPaintで描画.
表示領域を責任持って描画できるのであれば、WM_ERASEBKGNDは潰せる.
//ヘッダ
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
DECLARE_MESSAGE_MAP()
//実体
BEGIN_MESSAGE_MAP(CxxxWnd, CGlWnd)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
BOOL CImgScreen::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
}
- argc, argv
__argc, __argvを利用すれば良い.
- 外部プログラムの起動
ShellExecute( HWND hwnd,
LPCTSTR lpVerb,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
)関数.
HWND hwnd, // 親ウィンドウのハンドル
LPCTSTR lpVerb, // 操作
LPCTSTR lpFile, // 操作対象のファイル
LPCTSTR lpParameters, // 操作のパラメータ
LPCTSTR lpDirectory, // 既定のディレクトリ
INT nShowCmd // 表示状態
HINSTANCE Hnd = ShellExecute(NULL, "open", "Draw3D.exe", "256 256 50", NULL, SW_SHOW);
if((int)Hnd <= 32) {
g_str.Format("シェル起動に失敗しました。(Err Code:%d)", Hnd);
AfxMessageBox(g_str);
}
- CalcMaxMin
template <typename T>
void CalcMaxMin(T *src, int size, T *max, T *min)
//配列srcの最大値・最小値をmax,minに代入
{
ASSERT(FALSE==IsBadReadPtr(src,sizeof(T)*size));
int i;
*max=*min=*src;
for(i=1;i<size;i++){
*max = (*max < *src) ? *src : *max;
*min = (*min > *src) ? *src : *min;
src++;
}
return;
}
- SaveData
void SaveDat(char *filename, int size, float *dat)
{
FILE *fp;
int i;
fp=fopen(filename,"w");
if(fp==NULL)return;
for(i=0;i<size;i++){
fprintf(fp,"%f\n", dat[i]);
}
fclose(fp);
}
- _splitpath
絶対パスを構成要素に分解する.
void _splitpath(
const char *path, //分解したい文字列
char *drive, //ドライブ
char *dir, //パス
char *fname, //ファイル名
char *ext //拡張子
);
- INIファイル
iniファイルの読み込み
int g_sizex, g_sizey, g_frate;
TCHAR g_strShMem[BUF_LEN];
TCHAR g_strFileName[BUF_LEN];
g_sizex = GetPrivateProfileInt("Image","sizex", IMG_X, "./Draw3D.ini");
g_sizey = GetPrivateProfileInt("Image","sizey", IMG_Y, "./Draw3D.ini");
g_frate = GetPrivateProfileInt("Image","frate", FRAME_RATE, "./Draw3D.ini");
g_exe = (GetPrivateProfileInt("Mode","exe", EXE_FILELOAD, "./Draw3D.ini") == 0 )? EXE_FILEMAP : EXE_FILELOAD;
GetPrivateProfileString("Shmem", "ShMemName","ALAB_SHMEM", g_strShMem, BUF_LEN, "./Draw3D.ini");
GetPrivateProfileString("File", "FileName","test.txt", g_strFileName, BUF_LEN, "./Draw3D.ini");
- スタックサイズ
プロジェクト −> xxxのプロパティ −> リンカ −> システム
ー> スタックのサイズの設定
- パス
ツールー>オプションー>プロジェクトおよびソリューションー>VC++ディレクトリ
- M_PI
#define _USE_MATH_DEFINES
#include "math.h"
- Lapack
f2c.h 内でabs がマクロ関数として定義されているので、
math.h をインクルードする場合はf2c.h(clp.h) より前で行う。
f2c.h(clp.h) の後にmath.h をインクルードするとコンパイルエラーになる。
- RingUSB.h
44行目:Intel Compilerを使うとエラー
hUSB->ringusb::pUSBDevice=ringusb::pUSBDevice;
から
hUSB->pUSBDevice=ringusb::pUSBDevice;
に修正.
- LNK2005エラー
LIBCMT.lib(realloc.obj) : error LNK2005: __recalloc は既に msvcrt.lib(MSVCR80.dll) で定義されています。
などの表示.
プロジェクト>プロパティ>リンカ>入力>特定のライブラリの無視>LIBCMT.lib
など.
原因:MFCとランタイムライブラリの読み込む順番が違うらしい?
- プログラム中の解像度変更
DEVMODE devm;
EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &m_devm ); //現在のディスプレイ設定の保存
memcpy(&devm,&m_devm,sizeof(DEVMODE));
devm.dmSize=sizeof(DEVMODE);
devm.dmBitsPerPel=32;
devm.dmPelsWidth=m_width;
devm.dmPelsHeight=m_height;
devm.dmDisplayFrequency=m_rate;
ChangeDisplaySettings( &devm, CDS_FULLSCREEN);
- C1DFFT
ASSERTマクロを利用しているので, MFCが必要.
- スタティックライブラリの作成・利用
ファイル>新規作成>プロジェクト>Win32>Win32プロジェクト
適切なプロジェクト名を付けて、ファイルを追加. ビルド.できたlibを大切に保存.
使い方
-
プロジェクトのディレクトリにヘッダファイルとライブラリファイルをコピー.
-
プロジェクトにヘッダファイルを追加.
-
ヘッダファイルをインクルード
-
ライブラリをプリプロセスでリンク
#include "CImgWnd2.h"
#pragma comment(lib, "CImgWndLib.lib")
- C2DFFT
fftwとComplexとの共存.
g_fft1.GetData(reinterpret_cast<fftw_complex*>(Hx),FALSE);
- fftw_complexとstd::complexとキャスト
技巧的だが
fftw_complex testf[10];
for(int i=0;i<10;i++){
testf[i][0]=i;testf[i][1]=i*0.1;
}
for(int i=0;i<10;i++){
g_str.Format("%f+j%f", real(*(reinterpret_cast(&testf[i]))), imag(*(reinterpret_cast(&testf[i]))));
AfxMessageBox(g_str);
}
- OpenCV
OpenCVの導入