スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

MFCのCDialogでENTERキーで閉じるのを防ぐ方法

MFCのCDialogでENTERキーで閉じるのを防ぐ方法です。
(備忘録です)

CDialogのPreTranslateMessage()を処理してVK_RETURNの場合にCDialogの処理が行われないように
FALSEを返せばいいです。


BOOL CXXXXDlg::PreTranslateMessage(MSG* pMsg)
{
if( WM_KEYDOWN == pMsg->message ) {
switch( pMsg->wParam ) {
case VK_RETURN:
return FALSE;
default:
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}



ESCキーを無視したいときは、case VK_ESCAPEを入れればいいです。
もっと他のいい方法があったような気がしますが、
とりあえずこれで動きました。

ユーザID

以前書いたのですが、
チャットする人にはユーザIDをつけて、そのIDを使って部屋でチャットの通信をしています。
ユーザIDはCookieにひもつけてあって、リピータは既存のユーザIDを使えますが、
新規の人にはユーザIDを発行することになります。
実装としてはPostgreSQLでsequenceを作っていて、それで順番に番号を発行します。

そのユーザIDですが、最初の頃から約2年で6万少し増えています。
1年では3万ちょっとということですね。
1日になおすと80ちょっとくらい新規にIDをつけていることになります。

でもこれは普通にチャットするユーザばかりじゃなくて
クローラーが部屋にアクセスして、ユーザIDだけ新規につくってしまうってのがかなりあるんですよね。

まあこの程度ならIDが枯渇するなんてことはまったく気にしなくていいので安心ですね。

http://chattera.net/

MFCのListCtrlをソートする方法

MFCのListCtrlをソートする方法の備忘録です

まず、listにInsertItemをする際にSetItemData()でそのリストItemに関連するデータを設定します。
これは、ソートのCompareの際に、どのItemをCompareするのかを特定するための情報です。
例えば、Itemのデータを保持するエリアのポインタとか、配列のインデックス等です。

次にソートのCompare関数をstaticで定義します。
これはqsortのcompareと同じように、2つのItemをCompareして、どちらが前に来るかを返します。
(マイナスを返すCompareのと最初のItemが前で、プラスを返すと2番目のItemが前になります)

そして、このCompareを使って

CListCtrl.SortItem()を呼ぶことによって、ListCtrlの中のリストがソートされます。
このとき、選択されている行があれば、その行が移動した場合に、移動先の行が選択された状態になっています。

また、リストの見出し部分をクリックしてソートしたい場合が多いのですが、
その場合はLVN_COLUMNCLICKイベントをフックして



void CMyDlg::OnColumnclickList(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

index = pNMListView->iSubItem;


のようにして、クリックしたカラムを調べることができます。

また、見出し部分に▲のマークを出すには
CHeaderCtrl* pHeader = m_list.GetHeaderCtrl();
で取得されるヘッダの該当するカラムの属性として以下のようにHDF_SORTUPやHDF_SORTDOWNを設定すればいいようですが


CHeaderCtrl* pHeader = m_list.GetHeaderCtrl();
HDITEM hdrItem;
hdrItem.mask = HDI_FORMAT;
pHeader->GetItem(index, &hdrItem);
hdrItem.fmt |= HDF_SORTUP;
pHeader->SetItem(index, &hdrItem);

のようにすればいいようですが、VC++6.0の場合は、新しいcomctl32.dllを知らせるために
xmlのmanifestを登録しないといけないようなので、ややこしいです。

チャベリさんから直接取得してみた(続きの続き)

先日、チャベリ裏口さんが、調子悪いときに、チャベリから直接データを取得するようにしましたが、
昨日の夜からチャベリ裏口さんが調子悪いようですね。
それも、完全に取れないのではなく、一部のページが欠落するだけの状況が
ずっと続いているので、ここの表示も不完全な状態が続いてしまいます。
いままでは、こういう状態でもチャベリ裏口さんから取得するようにしていましたが、
長時間続いているようなので、一部のページが欠落しても、
チャベリから直接データを取得するように切り替えました。
早く正常に戻るといいですね。

http://chattera.net/
http://chattera.net/chaberilist.php

Javaでintのバイナリイメージを読み書きする

Cだと、int型整数のアドレスからsizeof(int)だけメモリに転送してやればいいので
簡単なのですがJavaだと1バイトずつ計算しないといけない。

intからbyte[]へは(LittleEndian)

buf[n ] = (byte)((a >> 0) & 0xFF);
buf[n+1] = (byte)((a >> 8) & 0xFF);
buf[n+2] = (byte)((a >> 16) & 0xFF);
buf[n+3] = (byte)((a >> 24) & 0xFF);


byte[]からintへは(LittleEndian)

(int)( ((buf[n ] & 0xff) << 0)|
((buf[n+1] & 0xff) << 8)|
((buf[n+2] & 0xff) << 16)|
((buf[n+3] & 0xff) << 24));


のような感じです。

ChatServerが動かなくなっていた

チャットルームに入ろうとして入れずに、ログも増えないので、変だとおもってみてみたら、
チャットサーバにSocketのConnectionエラーがでて
接続できない状態が続いていました。

仕方がないのでチャットサーバを再起動して復活させました。
前回起動したのが、2012年12月のログがあったので、
10ヶ月も停止せずに動き続けていたようです。
まあそれはいいことなのですが、
サーバへの接続でConnectionエラーがでるようになった原因はいまだに不明です。
ファイルディスクリプタも大きな値になってないので、
クローズし忘れというわけでもないようです。

http://chattera.net/

PoderosaでWrong key formatがでる場合

Poderosaでssh2の公開鍵を使って接続する場合に、もらった鍵ファイルでは
「Wrong key format」というエラーがでて接続できない場合があります。
それは鍵の形式が違うようなので、変換する必要があるということです。
その方法を備忘録として残しておきます。

・Puttyのサイトにいって、puttygen.exeをダウンロードする
  http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
 にあります。

・puttygen.exeを起動し、「Conversions → Import key」で
 元の鍵ファイルを読み込む。

・「Conversions → Export SSH.com key」で適当なファイル名をつけて保存する。

この保存した鍵ファイルを使えば、めでたく接続できました。

チャベリさんから直接取得してみた(続き)

先日のチャベリさんから直接取得するのは、
チャベリ裏口さんが復活したので、戻しておいたのですが、
今日も時々チャベリ裏口さんが応答を返さないというのが、何度かおきてます。

そこで、チャベリ裏口さんが応答を返さないか、返しても結果のデータが少ない場合は
その時刻のデータはチャベリさんに直接アクセスして取得するようにしました。
いわゆるハイブリッドですねww

これでしばらく様子を見てみようと思います。

http://chattera.net/
http://chattera.net/chaberilist.php

チャベリさんから直接取得してみた

チャベリ裏口さんが、時々調子悪くなるし
チャベリサーチさんがなぜかデータを取得しなくなっているので
今回は、チャベリさんから直接取得するようにしてみました。

以前ちょっと調べた取得の方法があるので、それを全部のページから取得できるように
突貫で作りました。
ただ、接続に応答がない場合などのエラー処理はいれてないので
そういう事態になった場合に、とまってしまうかもしれません。

また、一度の取得で、ページが20あり、それぞれ、HTMLと人のリストを取得する接続の
2つの接続が必要なので、計40回の接続になりますが、
チャベリさんはサーバがしっかりしているので、そのくらいはなんともないとは思いますが、
チャベリ裏口さん等が復活したら、元に戻しておこうと思います。

http://chattera.net/
http://chattera.net/chaberilist.php

ひさびさにはまった

MFCでDebugでビルドするとちゃんと動くのに、Releaseでビルドすると
ボタンを押したとたんにアプリケーションエラーで落ちる現象にあたってしまい
久々にはまりました。

場所を追ってみるとフレームワークに戻ってエラーになっているみたいで、
Releaseだと追って行けないので、余計なものをどんどん削っていきながら
最小の機能でエラーがでるまで追っていきました。
そうするとなんと、テンプレートから作成して、当該のコードをいれたものでも、
発生してしまいました。
ネットで調べてもそんなエラーの報告はないみたいです。
要するに入れたコードが何かまずいことをしているはずだと思って
調べていくと、やっとわかりました。

それは、フレームワークから呼ばれる関数の形式が
void XXXX();
でないといけないのに、
void XXXX(UINT);
にしていたということです。
わかってしまえば、こんな不注意なことを!ということなんですが、
やっている最中はわからないもんですね。

MFCのCFileDialogで複数のファイルを選択

MFCのCFileDialogで複数のファイルを選択しようとして
なぜか少ないファイルしか選択できないという現象になりました。

原因は、CFileDialogのm_ofnの持つバッファが少ないために、
たくさん選択するとエラーになってしまうというものでした。
コードとしては

CFileDialog dlg(TRUE, NULL, NULL,
OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY,
_T("すべてのファイル(*.*)|*.*||"));
dlg.m_ofn.nMaxFile = 1024*1024;
char *szFileNameBuffer = (char*)calloc(dlg.m_ofn.nMaxFile, 1);
dlg.m_ofn.lpstrFile = szFileNameBuffer;
if(dlg.DoModal() == IDOK)
{
POSITION pos = dlg.GetStartPosition();
while(pos)
{
AfxMessageBox(dlg.GetNextPathName(pos));
}
}
free(szFileNameBuffer);

のような感じにすればいいようです。

でも、普通はCFileDialogのdlg.DoModal()のなかで、足りなければ
内部で増やして返すような仕組みでできないもんですかね。

チャベリから直接取得するのは

チャベリ誰がいたのデータは、チャベリ裏口さんや、チャベリサーチさんから
取得するようにしているのですが、
チャベリ裏口さんは時々調子が悪くなったり、
チャベリサーチさんは一回の取得に25アクセスしないといけないので、
サーバに負荷がかかって迷惑かけるかな思っているので、
チャベリから直接取得する方法はないものかと思い、調べてみました。
まあ、細かくはかけないのですが、Socket接続していろいろすると
入室者の一覧くらいはとれるんですね。
とりあえず、チャベリから直接取得するようなスクリプトは途中まで書きましたが
いまはまだ使わないでおこうと思っています。

http://chattera.net/
http://chattera.net/chaberilist.php

16進ダンプデータをバイナリデータに変換するperlコマンド

16進ダンプでバイナリーデータをダンプした際の文字列を
実際のバイナリデータに変換したい場合があります。

たとえば、ダンプに

30313233343536373839

と出力されていた場合、

0123456789

のような文字列に変換してくれるようなものです。

こういったコマンドがないかと思い調べていたら
perlで簡単にできるんですね。


perl -ne 'print pack("H*",$_);'

このコマンドのstdinにダンプの文字列を渡せばいいです。
当然出力はバイナリですが、通常はこの目的では、表示可能な文字列を想定している場合が多いので
あまり悲惨なことにはならないと思います。

ちなみに逆変換は

perl -ne 'print unpack("H*",$_);'

になります。


チャベリ裏口さんのDNSが見つからない?

チャベリ裏口さんは、ときどき応答がなくなったりしているのですが、
今回はDNSが見つからないというエラーになってしまいますね。
dyndnsというサービスを使われているようで、
ここと何かあったんですかね。
ちょっと心配です。
復活してくれればいいのですが。。

http://chattera.net/
http://chattera.net/chaberilist.php

file_get_contentsでのアクセス時にuseragentを指定する

file_get_contentsでのアクセス時にuseragentを指定する方法のメモです。


$context = stream_context_create(array(
  'http' => array(
   'header' => 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36',
    ),
 )
);
$htmlstr = file_get_contents($filename, $use_include_path, $context);


のようにstream_context_create()を作って headerにUser-Agentを含む文字列を渡せばいいようです。
User-Agentの他にHeaderを渡したい場合は


   'header' => "User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36\r\nFoo: Bar",


のように\r\nの改行つきで渡せばいいようです。


   'header' => 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36\r\nFoo: Bar',

のようにシングルクオートでセットしてしまうと、\r\nがそのままの文字でくっついてしまって
「Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36\r\nFoo: Bar」
という文字がUserAgentになってしまいます。

ここのアクセス解析がトラブル

ここのアクセス解析がトラブっているみたいですね。
7月分のデータが見えないという現象はうちでは発生してないのですが、
そのかわり解析ページとして設定したものが、かなり古いものに戻っていますね。
DBが壊れて復旧したら、かなり過去のバックアップを戻してしまったという感じですね。
ということは、新しいものはすでに存在しないということなんですかね。
また設定しなおさないといけないかも。。

http://chattera.net/
http://chattera.net/chaberilist.php

チャベリ裏口さん一時不調

先月もあったのですが、今日も一時チャベリ裏口さんが数時間にわたって不調になっていました。
たまたま気づいたので、チャベリサーチさんに切り替えたのですが、
自動で切り替えることを検討したほうがいいですかね。
でも、不調、復活を定義するのもけっこうややこしいかもしれませんね。
まったく応答がないなら、すぐわかるのですが、
一部ページだけが存在してて、データはくるものの、
それが全部なのか一部なのかって、判断するのもなかなか面倒かもしれませんね。

http://chattera.net/
http://chattera.net/chaberilist.php

MySQLのcurrent_timestamp

MySQLでcreatedとmodifiedに

modified timestamp not null on update current_timestamp default current_timestamp
created timestamp not null default 0,

のようにして、登録日時(created)と更新日時(modified)を設定するということがありましたが、
これらのカラムの前に同じtimestampでnot null default がないtimestampのカラムを
入れるとエラーになります。。


accessed timestamp,
modified timestamp not null on update current_timestamp default current_timestamp
created timestamp not null default 0,

だと

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

がでますね。(MySQL 5.1)

accessed timestamp,



accessed timestamp not null default 0,

にしたり

accessed datetime,

にすれば大丈夫ですね。
あとはmodifiedの後ろに持ってくるとか。

もっとエラーメッセージをわかりやすくしてくれないと、何がエラーなのか、MySQLのバグなのか仕様なのか
わからないですね。

MySQLのcreatedとmodified

MySQLでレコード追加日時をcreated、レコード更新日時をmodifiedという名前にして
新規レコードが追加されたときにcreatedがその時刻になり、
レコードが更新されたときに自動的にmodifiedが更新される、お決まりの方法の備忘録です。


modified timestamp not null on update current_timestamp default current_timestamp
created timestamp not null default 0,


こんな感じで書くようです。
注意としてはcurrent_timestamp を設定できるのは1カラムだけということらしいので
createdはこのようにするしかないみたいです。

そしてレコードを追加する際には createdにnullを設定すればいいみたいです。

PHPで文字列から1文字ずつ取り出す

PHPで文字列を1文字ずつ取り出す方法のメモです。

1.str_split()をつかう
2.preg_match_all()で "(.)"を渡す
3.文字列を配列として[]を使って取り出す(PHP5以上)

という方法があるようです。


<?php


$str = "This is string split test";

$a1 = str_split($str);
print_r($a1);

preg_match_all("(.)", $str, $a2);
print_r($a2);

function mysplit($str){
$array = array();
for ($i = 0; $i < strlen($str); $i++){
$c = $str[$i];
array_push($array,$c);
}
return $array;
}

$a3 = mysplit($str);
print_r($a3);



結果は

$ php split.php
Array
(
[0] => T
[1] => h
[2] => i
[3] => s
[4] =>
[5] => i
[6] => s
[7] =>
[8] => s
[9] => t
[10] => r
[11] => i
[12] => n
[13] => g
[14] =>
[15] => s
[16] => p
[17] => l
[18] => i
[19] => t
[20] =>
[21] => t
[22] => e
[23] => s
[24] => t
)
Array
(
[0] => Array
(
[0] => T
[1] => h
[2] => i
[3] => s
[4] =>
[5] => i
[6] => s
[7] =>
[8] => s
[9] => t
[10] => r
[11] => i
[12] => n
[13] => g
[14] =>
[15] => s
[16] => p
[17] => l
[18] => i
[19] => t
[20] =>
[21] => t
[22] => e
[23] => s
[24] => t
)

)
Array
(
[0] => T
[1] => h
[2] => i
[3] => s
[4] =>
[5] => i
[6] => s
[7] =>
[8] => s
[9] => t
[10] => r
[11] => i
[12] => n
[13] => g
[14] =>
[15] => s
[16] => p
[17] => l
[18] => i
[19] => t
[20] =>
[21] => t
[22] => e
[23] => s
[24] => t
)


となります。
プロフィール

chattera.net

Author:chattera.net
フリーでソフト開発の仕事をしています。
自作したこのチャットシステムは、何か世の中に役に立つこともあるかと思いますので、お呼びがかかるとうれしいですね。

連絡先は chatteranet@gmail.com です。

また、ソフト開発関連のお誘いもうけたまわっております。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。