VC覚書きページへ
トップページへ戻る...



Memo -010. (98/01/13)
ロケールに依存した関数 (CTime::Format("%x"), ::strftime(..)) などを使った時、
コントロールパネルで設定した書式にする方法。
::setlocale(LC_ALL, ""); // この関数を InitInstance あたりに入れておく。
locale.h をインクルードすること。より詳しくは、ヘルプの「国際化対応」を参照。

(setlocale 自体は早くから知ってたけど引数を "" にするとOSデフォルトになることに気づかず 2日ぐらいずっと悩んでました。(笑))


Memo -009. (98/01/13)
Memo -007.のもう一つの方法
-007の方法では、CPropertySheet のせいで、レイアウトが若干制限されるみたい。
もっときれいにレイアウトをしたいなら、ダイアログの上にモードレスのダイアログを張る方がいい。
ベースダイアログに CTabCtrl をつけて、それで貼り付けたダイアログを切り替える。

BOOL CMyDialogBase::OnInitDialog()
{
CDialog::OnInitDialog();
TC_ITEM tc;
tc.mask = TCIF_TEXT;

tc.pszText = "2次元表示操作パネル";
m_tab.InsertItem(0, &tc); // m_tab はTabctrl
m_pDlgPP2D = new CDialog;
m_pDlgPP2D->Create(IDD_PP2D, this);
m_pDlgPP2D->ShowWindow(SW_SHOW);
m_pDlgPP2D->SetWindowPos(...);

tc.pszText = "3次元表示操作パネル";
m_tab.InsertItem(1, &tc);
m_pDlgPP3D = new CDialog;
m_pDlgPP3D->Create(IDD_PP3D, this);
m_pDlgPP3D->ShowWindow(SW_HIDE);
m_pDlgPP3D->SetWindowPos(...);

return TRUE;
}

// Tab Ctrl の選択が変わったら void CDlgViewCtrl::OnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult)
{
switch (m_tab.GetCurSel())
{
case 0:
m_pDlgPP2D->ShowWindow(SW_SHOW);
m_pDlgPP3D->ShowWindow(SW_HIDE);
break;
case 1:
m_pDlgPP2D->ShowWindow(SW_HIDE);
m_pDlgPP3D->ShowWindow(SW_SHOW);
break;
}
*pResult = 0;
}


Memo -008. (98/01/07)
SDIにて複数ビューを使う方法
必要なビューを CMainFrame にメンバとして登録(m_pMainView, m_pSubView など)
OnCreateClient()をオーバーライトする。
ビュー変更用の関数を作る。

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
pContext->m_pNewViewClass = RUNTIME_CLASS(CMainView);
m_pMainView = (CMainView*)CreateView(pContext, AFX_IDW_PANE_FIRST);
pContext->m_pNewViewClass = RUNTIME_CLASS(CSubView);
m_pSubView = (CSubView*)CreateView(pContext, AFX_IDW_PANE_FIRST+1);
return TRUE;
}

BOOL CMainFrame::ChangeView(CView* pNewView)
{
if(!pNewView)
return FALSE;
CView* pNowView = GetActiveView();
if(!pNowView)
return FALSE; //考えられないが

if(pNowView == pNewView)
return FALSE;

// Viewの子ウインドウIDの入換え
int nNowViewID = pNowView->GetDlgCtrlID();
int nNewViewID = pNewView->GetDlgCtrlID();
pNowView->SetDlgCtrlID(nNewViewID);
pNewView->SetDlgCtrlID(nNowViewID);

pNowView->ShowWindow(SW_HIDE); //いま表示されていのを消す
pNewView->ShowWindow(SW_SHOW); //指定のビューを表示する
SetActiveView(pNewView);
RecalcLayout(); //フレーム内の位置を再計算
return TRUE;
}

void CMainFrame::OnChView() // ビュー変更メッセージハンドラ
{
if (GetActiveView() == m_pMainView)
ChangeView(m_pSubView);
else
ChangeView(m_pMainView);
}


Memo -007. (98/01/05)
プロパティシート中に共通に使いたいコントロールがある場合は、そのコントロールをCDialogに作り、 そのダイアログにプロパティーシートをモードレスで作り適当な位置に移動させる。
(具体的には、VC++ のプロジェクト設定ダイアログみたいなもの)
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();

m_pps = new CPropertySheet; // 実際は派生クラスでしょう
m_ppp1 = new CPropertyPage(IDD_PP1); // 同上
m_ppp2 = new CPropertyPage(IDD_PP2); // 同上

m_pps->AddPage(m_ppp1);
m_pps->AddPage(m_ppp2);
m_pps->Create(this, WS_CHILD |WS_VISIBLE, WS_EX_CONTROLPARENT);
m_pps->MoveWindow();

return TRUE;
}


Memo -006. (98/01/04)
ネットワーク機能を使うには WNet で始まる関数を使う。
winnetwk.h と mpr.lib が必要。(stdafx.h の #define VC_EXTRALEAN をコメントにすれば .h はインクルード済になる)
〜よく使う関数〜
::WNetConnectionDialog(); // 接続ダイアログ表示
::WNetDisconnectDialog(); // 切断ダイアログ表示
::WNetAddConnection2(); // ネットワークのドライブ接続
::WNetCancelConnection2();// 切断


Memo -005.
リモートアクセス関連は、RAS で始まる関数を使う。
ras.h と rasapi32.lib が必要。
〜よく使う関数〜
::RasDial(); // リモート接続
::RasHangUp(); // リモート接続切断


Memo -004.
Folder 選択ダイアログの表示 (Win95/NT40)
char pszPath[_MAX_PATH];
ITEMIDLIST* pidl;
::SHGetSpecialFolderLocation(this->GetSafeHwnd(), CSIDL_DRIVES, &pidl);
BROWSEINFO bi;
::ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.hwndOwner = this->GetSafeHwnd();
bi.pidlRoot = pidl; // NULL の時マイコンピュータから表示
bi.pszDisplayName = pszPath;
bi.lpszTitle = "フォルダを選択してください";
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
//bi.lParam
//bi.iImage
pidl = ::SHBrowseForFolder(&bi);
::SHGetPathFromIDList(pidl, pszPath);
で、pszPath に選択したフォルダのパスが入っている。
NT3.51とかは、CFileDialog をカスタマイズするらしい。
stdafx.h 内の #define VC_EXTRALEAN をコメントにし、 shlobj.h をインクルードすること。

Memo -003.
ダイアログに貼り付けたコントロールのサブクラス化は、(例えば CCtrlListEx)
OnInitDialog() で SubclassDlgItem() を使う。

ダイアログエディタでリストコントロールを作る。(IDC_LISTCTRL)

class CMyDlg : public CDialog
{
CCtrlListEx m_ListCtrl;
...
};

BOOL CMyDlg::OnInitDialog()
{
m_ListCtrl.SubclassDlgItem(IDC_LISTCTRL, this);
CDialog::OnInitDialog();
...
return TRUE;
}
SubclassDlgItem() の位置に注意


Memo -002.
SDIを実行時に最大化するには InitInstance()の最後のほうに
m_nCmdShow = SW_SHOWMAXIMIZED; // 最大化
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
の3行を入れる。


Memo -001.
::CreateProssece()
で起動した別のプログラムの終了コードは、
::GetExitCodeProcess()
でわかる。