■動作環境 :WindowsXP
■開発環境 :Visual C++6.0(ダイアログベース)
■データベース :Access2000(ADO接続)
いつもお世話になります。
ダイアログに月間予定表を貼り付けて日付をとって、それを元にして
Accessのデータを表示させるプログラムを作っています。
カレンダーのクリックした日を取りたいのですが
カレンダーにカーソルがあたっていないと取ってくれません。
(私は日にちをクリックした時点でカーソルはカレンダーにあたっていると
思っていました)
フォーカスがあたっている時は日付を取ってくれていますが、これもクリック
してとゆうよりも選択されていたら取得してるようです。
1.クリックした日をとる場合はどうすればいいか教えてください。
2.OKボタン以外はEnterを使えないようにしているのですが
日にちを選択してEnterを押下しますと画面が消えてしまいます。
カレンダー自体はEnterを押下しても消えないので、カレンダー
の中の日付を制御する方法を教えてください。
3.プログラムの書き方で修正したほうがいい箇所がありましたら、
教えてください。(独学ですので普通はこのようにやるのかとゆう不安と
無駄な処理が多そうな気がする為)
よろしくお願い致します。
2006年10月
日 月 火 水 木 金 土
24 25 26 27 28 29 30
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 1 2 3 4
<以下プログラム>
BOOL CZzzDlg::PreTranslateMessage(MSG* pMsg)
{
CString Year;
CString Month;
CString Day;
// IDC_BUTTON1 以外はEnter無効
if(GetFocus() != GetDlgItem(IDC_BUTTON1)){
if(pMsg->wParam == VK_RETURN) { // エンターキー
return FALSE;
}
else if(pMsg->wParam == VK_ESCAPE) { //エスケープキー
return FALSE;
}
}
// フォーカスがカレンダーの時
if(GetFocus() == GetDlgItem(IDC_MONTHCALENDAR2)){
//左クリックしたら
if(pMsg->wParam == VK_LBUTTON){
// 月間予定表 コントロールの機能
CMonthCalCtrl* pMonthSel;
// 月間予定表のコントロールのウィンドウハンドルを取得
pMonthSel = (CMonthCalCtrl *)GetDlgItem(IDC_MONTHCALENDAR2);
// 現在選択されている日付情報を取得
SYSTEMTIME st;
pMonthSel->GetCurSel(&st);
int wYear = st.wYear; // SYSTEMTIME型 ~ int型
int wMonth= st.wMonth; // SYSTEMTIME型 ~ int型
int wDay = st.wDay; // SYSTEMTIME型 ~ int型
Year.Format(%d, wYear); // int型 ~ CString型
Month.Format(%d, wMonth); // int型 ~ CString型
Day.Format(%d, wDay); // int型 ~ CString型
CString Date = Year + '/' + Month + '/' + Day; // 年/月/日 をセット
// 日付を表示
AfxMessageBox(Date);
}
}
return CDialog::PreTranslateMessage(pMsg);
}
3.だけ。
> // 現在選択されている日付情報を取得
> SYSTEMTIME st;
> pMonthSel->GetCurSel(&st);
>
> int wYear = st.wYear; // SYSTEMTIME型 ~ int型
> int wMonth= st.wMonth; // SYSTEMTIME型 ~ int型
> int wDay = st.wDay; // SYSTEMTIME型 ~ int型
>
> Year.Format(%d, wYear); // int型 ~ CString型
> Month.Format(%d, wMonth); // int型 ~ CString型
> Day.Format(%d, wDay); // int型 ~ CString型
>
> CString Date = Year + '/' + Month + '/' + Day; // 年/月/日 をセット
(ミリ秒まで使わない場合)
CTimeを引数にとる GetCurSelメソッドを使ったほうが便利。
CTime t;
pMonthShel->GetCurSel( t );
CString Date = t.Format( _T( %Y/%m/%d ) );
あーすいません。
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200205/02050077.txt
だそうです。
ただ
> int wYear = st.wYear; // SYSTEMTIME型 ~ int型
> int wMonth= st.wMonth; // SYSTEMTIME型 ~ int型
> int wDay = st.wDay; // SYSTEMTIME型 ~ int型
>
> Year.Format(%d, wYear); // int型 ~ CString型
> Month.Format(%d, wMonth); // int型 ~ CString型
> Day.Format(%d, wDay); // int型 ~ CString型
>
> CString Date = Year + '/' + Month + '/' + Day; // 年/月/日 をセット
はムダが多いので CString::Formatメソッドを使って
CString Date;
Date.Format( %04d/%02d/%02d, st.wYear, st.wMonth, st.wDay );
といっぺんに書いてしまえばいいのではないでしょうか。
>PreTranslateMessage
でCMonthCalCtrlのクリックをとっているようですが
CMonthCalCtrlのMCN_SELECT、MCN_SELCHANGEイベントあたりではダメなんでしょうか?
>月間予定表からの右クリックでの日付のとり方
あ、右クリックならMCN_SELECT、MCN_SELCHANGEイベントは誤爆です。
あと
>// IDC_BUTTON1 以外はEnter無効
のところですが、wParam はメッセージによっていろいろな値が入ってくるので
判定前に必ず、
if ( pMsg->wParam == WM_KEYDOWN )
の判定文が必要ではないでしょうか?
1.
イベント取得は、WM_NOTIFY メッセージ
MCN_SELECT --- 日付押した時
MCN_SELCHANGE --- 上部の日付入力欄で年度などを変えた時
2.
推測ですが、初めにIDC_BUTTON1にフォーカスを置いてない場合
操作すると問題ないのでは
// IDC_BUTTON1 以外はEnter無効
if(GetFocus() != GetDlgItem(IDC_BUTTON1)){
if(pMsg->wParam == VK_RETURN) { // エンターキー
return FALSE;
}
else if(pMsg->wParam == VK_ESCAPE) { //エスケープキー
return FALSE;
}
void OnOK(){}
void OnCansel(){}
を無効にし
OKボタンは別のIDで作った方が楽なような気がします
3.
MFC を使っているようなので
DDXやメッセージマップを使った方が良いのでは
ADO なら、時刻はCOleDateTimeの方が処理しやすいと思います。
Blueさんいつもありがとうございます。
MKさんありがとうございます。
>CString Date;
Date.Format( %04d/%02d/%02d, st.wYear, st.wMonth, st.wDay );
私も無駄をやっていると思ったのですが、この方法が分かりませんでした。
今後はこのようなやり方でやります。
すみませんでした右クリックでなく左クリックでした。
表題も間違えているので、一回これを閉じてもう一度スレッドを立ち上げます。
本当に申し訳ありません。