ラベル 技術メモ の投稿を表示しています。 すべての投稿を表示
ラベル 技術メモ の投稿を表示しています。 すべての投稿を表示

2013年11月12日火曜日

[c#]DataGridViewのマウスホイールでのスクロールを1行単位にする

こちらのサイトにありました。

 DataGridViewはマウスホイールのスクロールで3行送りです。(OS設定に依存します)
このスクロール量を1行送りに変えます。

DataGridViewを継承したクラスを作って、OnMouseWheelでチョイチョイとすればいい感じになります。

MouseEventArgsコンストラクターの第5引数が若干意味不明です。
なにやら、マウスホイールの1ラッチで120単位の移動量となるとか、説明を見てもよくわかりません。

実行すると、マウスホイールを手前に1ラッチすると、e.Deltaには-120が入っています。
MouseWheelScrollLinesには3が入っています。

つまり、第5引数には-40を設定すれば、1行送りになるかというと、確かにそうなります。
マウスの設定でスクロールする行数を1に変更しても、e.Deltaには-120が入ってきます。
この場合、-120でも1行送りになります。

どういう仕組なの?

よくわかりませんが、結果オーライで行きます。

public class DataGridViewEx : DataGridView
{
    // ホイールマウス制御
    protected override void OnMouseWheel(MouseEventArgs e)
    {
        // マウス ホイールを回転したときにスクロールする行数を取得
        Int32 scroll = SystemInformation.MouseWheelScrollLines;

        // MouseEventArgsクラスの移動量を1行に変更
        MouseEventArgs ex = new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, e.Delta / scroll);

        base.OnMouseWheel(ex);
    }
}

2013年11月1日金曜日

[c#]フォームが1つしか表示されないようにする

メインフォームとサブフォームがあって、サブフォームはモードレスで表示する場合に、サブフォームが1つだけ表示されるようにする方法です。


private SubForm _subForm = null;
private void showSubForm()
{
    //フォームが表示されているかの判定
    if (this._subForm == null || this._subForm.IsDisposed)
        this._subForm = new PlanListForm();

    if (!this._subForm.Visible)
    {
        this._subForm.Show();
    }
    else
    {
        this._subForm.Activate();
    }

}

2013年9月4日水曜日

[SQL Server] SQL Serverでテーブル定義取得(全テーブル)

SQL Serverで、テーブル定義らしいものを取得するクエリです。
これとの違いは、データベース内のすべてのテーブルについて出力します。

select
 obj.name as 'テーブル名'
,col.name as '名称'
,(select top 1 name from systypes where systypes.xtype = col.xtype) as '型'
,col.length as '桁数'
,case isnull(col.scale,0)
 when 0 then ' '
 else cast( col.scale as char(10) )
 end '小数部'
,case  col.isnullable
 when 0 then '○'
 else ' '
 end 'nn'
,isnull((select case colid when 0 then '' else '○' end  from sysindexkeys as keys where col.id = keys.id  and col.colid = keys.colid and keys.indid = 1),' ') as 'pk'
,isnull((select top 1 ex.value from sys.extended_properties as ex where col.id = ex.major_id and ex.minor_id = col.colid and ex.name = 'ms_description' ),' ') as 'コメント'
from syscolumns as col
inner join sysobjects as obj on col.id = obj.id
where obj.name in  (select name from sysobjects where xtype = 'u')

2013年4月23日火曜日

[c#]VSテストプロジェクトで単体テストのカバレッジが100%にならなかった点の対策

Visual Studio Team System 2008にてテストプロジェクトを利用して、単体テストを行っています。
また、このエディションではコードカバレッジを取れるので100%にすることも要件にしています。

その中で見た目は処理が通っているのですが、カバレッジが100%にならないケースが出てきました。
以下がその例です。


public void Method01(System.Windows.Forms.Control.ControlCollection list)
{
    List<control> wk = new List<control>();
    foreach (Control tmp in list)
    {
        if (tmp is Label) continue;
        wk.Add(tmp);
    }
}


Collectionをforeachしているだけなのですが、これが問題のようです。
詳しい理由はわかりませんが、裏方さんのコードに通らないパスがあるっポイです。
とにかく、Collectionをforeachするとダメなので、Listをforeachするように変える処理を入れます。


//CollectionをListに変換する
public List<t> ConvertList<t>(ICollection collection)
{
    List<t> ret = new List<t>();
    IEnumerator tmp = collection.GetEnumerator();
    
    while(tmp.MoveNext()) {
        ret.Add((T)tmp.Current);            
    }
    return ret;
}


それで、foreachの所でこのメソッドを使います。


public void Method01(System.Windows.Forms.Control.ControlCollection list)
{
    List<control> wk = new List<control>();
    foreach (Control tmp in ConvertList<Control>(list))
    {
        if (tmp is Label) continue;
        wk.Add(tmp);
    }
}


これでカバレッジが100%になるようになりました。

2013年2月20日水曜日

[php]翌月の末日の取得

phpにて翌月の末日を取得する方法です。

date("Y-m-t" ,strtotime("+1 month"));

2012年12月21日金曜日

[MySQL]Windows7(64bit)でcseを使ってMySQLに接続

環境は以下の通りです。
サーバー:Windows 2000 sp4、MySQL 5.1.66
クライアント:Windows7(64bit)

このクライアントでcse(Common SQL Environment)を使った時のメモです。

1.MySQL odbcドライバのインストール
MySQLのバージョンが3以上だと、odbcからしかつなげないとの事。
MySQLのサイトからodbcドライバー「Windows (x86, 64-bit), MSI Installer Connector-ODBC」をダウンロードしてインストール。
この時のバージョンは5.2.2でした。
http://www.mysql.com/downloads/connector/odbc/

2.odbcドライバの設定
コントロールパネルからデータソースを選択して、ユーザーDSNタブにて、追加ボタンを押下。
「MySQL ODBC 5.2w Driver」を選択して完了を押下。
続いてodbcの設定。
Charset Setに「sjis」を書かないと、後でcseに表示した日本語が文字化けします。
ちなみにMySQLの環境はUTF-8です。

3.cseからの接続
後はcseの接続で、DBMSに「ODBC汎用」を選び、データソース、ユーザ名、パスワードを入力すれば接続できます。

補足:最初のうちはcseの起動時に「libmysql.dllが見つからない」と言われてましたが、odbcドライバを5.1.1から5.2.2に変えたら(だと思う)怒られなくなりました。



2012年7月6日金曜日

[Windows Phone]リソースの画像ファイル取得ではまった

リソースの画像ファイル(プロジェクトに登録した画像)を、プログラムから取り出して表示したかったのですが、なかなか取り出せませんでした。
1.pngファイルを Images/Category/Image01.pngとして登録
2.画像のプロパティ「ビルドアクション」を「コンテンツ」に設定
3.以下のコードで実行

StreamResourceInfo source = Application.GetResourceStream(new Uri("/Images/Category/Image01.png", UriKind.Relative));
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(source.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);

これで実行しても、StreamResourceInfoはnullになってしまいます。
間違っているのは1行目のパス設定方法。
正しくは以下になります。

StreamResourceInfo source = Application.GetResourceStream(new Uri("Images/Category/Image01.png", UriKind.Relative));
画像パスの指定で先頭のスラッシュを消しました。
これで読み込むことが出来ました。

ルートがどこかは不明です。

2012年5月15日火曜日

汎用命名ルール

サーバーやPC、プログラムにドメインと名前をつける機会が多いのですが、
名前をつけるルールが決まっていると、悩まずに済むし覚えやすく統一性ももたせられます。

注意点としては将来的な構成数を想定してからルールを決める必要があります。
目的に特化した名前も、時間と共に目的が変化した際に相違が出てしまいます。
また、物によっては名称が長すぎるので省略して使うのも良いと思います。

都道府県
http://ja.wikipedia.org/wiki/%E9%83%BD%E9%81%93%E5%BA%9C%E7%9C%8C#.E5.90.8D.E7.A7.B0

日本の伝統色の名前
http://www.colordic.org/w/

フォネティックコード
http://ja.wikipedia.org/wiki/NATO%E3%83%95%E3%82%A9%E3%83%8D%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B3%E3%83%BC%E3%83%89

元素名
http://ja.wikipedia.org/wiki/%E5%85%83%E7%B4%A0%E3%81%AE%E4%B8%80%E8%A6%A7

木星の衛星
http://en.wikipedia.org/wiki/Moons_of_Jupiter

星座の名前
http://ja.wikipedia.org/wiki/%E6%98%9F%E5%BA%A7

ギリシャ神話の登場人物
http://en.wikipedia.org/wiki/Twelve_Olympians

犬の種類
http://inunoshurui.sblo.jp/

山手線の駅名
http://www.jreast.co.jp/estation/result.aspx?mode=2&rosen=66=1=%8ER%8E%E8%90%FC

世界の首都名
http://www1.coralnet.or.jp/ravel/world.html

国際空港コード
http://www.k-tanaka.net/airport/airport_code.html

魚貝類をローマ字表記
aji,saba,sanma,ika,tako,asari,fugu

日本っぽい植物をローマ字表記
sakura,tanpopo,suisen,momo


参考リンク
http://mojix.org/2011/01/24/server-naming
http://www.kojii.net/pc/server_name.html
http://d.hatena.ne.jp/masahiror/20060904/naming_matome
http://slashdot.jp/poll/285?aid=-1

2012年4月5日木曜日

[android]androidライブラリの作り方・使い方


カスタムコントロールではなくて、ウィジットというのでしょうか。
android.widget.Buttonを継承したクラスをライブラリにする手順のメモです。
# ここではButtonをつかってますが、他のウィジットでもやり方は一緒です。
環境はEclipse3.7です。

・androidプロジェクトを「アクティビティーの作成」のチェックを外して作成する。

・プロジェクトのプロパティでandroidの項目を選択し、ライブラリーの「Is Library」のチェックを入れる。

・resディレクトリー配下のファイル、ディレクトリーを削除する。
・androidManifest.xmlのアプリケーションタブにて「Define an <application> tag in AndroidManifest.xml」のチェックを外す。

・srcディレクトリーを右クリックしてクラスを追加。スーパークラスに「android.widget.Button」を指定する。


続いて使い方です。
今回は同一ワーキングスペースでのケースです。

・androidプロジェクトを新規に作成する。
・プロジェクトのプロパティでandroidの項目を選択し、ライブラリーの「追加」ボタンを押下で上記で作成したプロジェクトを選択する。
・自作ボタンクラスを継承したクラスを作成する。
public class exButton extends LibButton {
 public exButton(Context context, AttributeSet attrs)
 {
  super(context, attrs);
 }
}

・main.xmlにパッケージ名を含めたクラス名を利用してタグを記述する。

<com.feelg.android.androidLib.exButton
 android:id="@+id/exButton01"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"  />

以上で使えました。
まだまだ勉強不足です。

2012年3月13日火曜日

[jQuery]Lazy Loadで負荷低減できるか?

あるホスティングサービスで503エラーが出始めたため、
原因を調査したら同時アクセス数が増えてきた事が一番の原因のようでした。
そのサイトは画像を大量に利用することも原因に挙げられます。

なにか良い方法が無いかと調べたところ、画面の表示領域付近に近づいてから対象の画像を読み込むと言うjQueryプラグインがありました。

Lazy Load

使い方は非常に簡単です。
まず、<head>にjQueryと上記のプラグインを読み込みこんで、その実行コードを書きます。
以下のコードではオプション設定で、画面の表示範囲より200px広い範囲までをフェードインで読み込む。って感じです。







後は遅延ロードさせたい画像タグを以下のように書きます。
srcにはダミーの画像を設定しておき、data-originalに実際に読み込ませる画像を記述します。



これだけです。


とりあえず、503エラーの発生率は下がったので効果はあったと言えそうです。
ただ、完全には無くなってないので別の対策も必要そうです。

2012年1月26日木曜日

[PHP]AESで暗号化・復号化

暗号化と復号化する処理です。
基本的にはmanualに書いてある通りです。

受け取った文字をbase64でエンコードして、暗号化して、暗号化した文字もbase64でエンコードしています。
復号化の際も同じ感じです。

暗号・復号処理に関していつものことなのが、これがAESでうまく暗号化されているかはよく分からず、復号化がうまくいっているので良しとしています。


static public function Encrypt($value){

 //Base64でエンコードする
 $encodedValue = base64_encode($value);

 /* 暗号モジュールをオープンします */
 $td = self::getCryptModule();

 /* データを暗号化します */
 $encrypted = mcrypt_generic($td, $encodedValue);

 //暗号化された文字をBase64でエンコードする
 $encodedEncryptValue = base64_encode($encrypted);

 /* 暗号化ハンドラを終了します */
 mcrypt_generic_deinit($td);

 /* モジュールを閉じます */
 mcrypt_module_close($td);

 return $encodedEncryptValue;
}


static public function Decrypt($value){

 //Base64デコードする
 $decodedValue = base64_decode($value);

 /* 暗号モジュールをオープンします */
 $td = self::getCryptModule();

 /* 暗号化された文字列を復号します */
 $decrypted = mdecrypt_generic($td, $decodedValue);

 /* 復号ハンドルを終了し、モジュールを閉じます */
 mcrypt_generic_deinit($td);
 mcrypt_module_close($td);

 //Base64デコードする
 $decodedDecryptValue = base64_decode($decrypted);

 return $decodedDecryptValue;

}

static private function getCryptModule()
{

 /* 暗号モジュールをオープンします */
 //$td = mcrypt_module_open('tripledes', '', MCRYPT_MODE_ECB, '');
 $td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_ECB, '');

 /* IV を作成し、キー長を定義します。Windows では、かわりに
  * MCRYPT_RAND を使用します */
 $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
 $ks = mcrypt_enc_get_key_size($td);

 /* キーを作成します */
 $key = substr(md5('very secret key'), 0, $ks);

 /* 復号用の暗号モジュールを初期化します */
 mcrypt_generic_init($td, $key, $iv);

 return $td;
}


2012年1月23日月曜日

[C#]画像に文字を埋め込んで保存する

画像の中心に指定の文字列を埋め込んで保存する処理です。
DOBON.NETさんを参考に保存のあたりの処理を加えています。


private void drawString(FileInfo copiedfi,string s,Font font)
{
 int quality = 85;

 //一時ファイルの作成
 string tmpFilename = copiedfi.FullName + ".tmp";
 FileInfo tmpFi = copiedfi.CopyTo(tmpFilename, true);

 //Bitmapオブジェクトの生成
 using (Bitmap bmp = new Bitmap(tmpFi.FullName))
 {
  //解像度の設定
  bmp.SetResolution(72, 72);

  //Graphicsオブジェクトを取得
  using (Graphics g = Graphics.FromImage(bmp))
  {
   //画像を描画する
   g.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height);

   //白のブラシを作成する
   using( Brush b = new SolidBrush(System.Drawing.Color.White))
   {
    //文字の領域サイズを取得する
    StringFormat sf = new StringFormat();
    SizeF stringSize = g.MeasureString(s, font, bmp.Width, sf);

    //文字を描画する
    g.DrawString(s, font, b, (bmp.Width / 2) - (stringSize.Width / 2), (bmp.Height / 2) - (stringSize.Height / 2));
   }

  }

  //品質を指定
  System.Drawing.Imaging.EncoderParameters eps = new System.Drawing.Imaging.EncoderParameters(1);
  eps.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

  //エンコーダーを取得する
  System.Drawing.Imaging.ImageCodecInfo ici = this.getEncoderInfo("image/jpeg");

  bmp.Save(copiedfi.FullName, ici, eps);

 }

 //一時ファイルの削除
 if( File.Exists(tmpFilename) )File.Delete(tmpFilename);

}

//MimeTypeで指定されたImageCodecInfoを探して返す
private System.Drawing.Imaging.ImageCodecInfo getEncoderInfo(string mineType)
{
 //GDI+ に組み込まれたイメージ エンコーダに関する情報をすべて取得
 System.Drawing.Imaging.ImageCodecInfo[] encs = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
 //指定されたMimeTypeを探して見つかれば返す
 foreach (System.Drawing.Imaging.ImageCodecInfo enc in encs)
  if (enc.MimeType == mineType)
   return enc;
 return null;
}

2011年12月16日金曜日

[Windows Phone]USER_AGENT

Windows Phoneのユーザーエージェントです。
Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; FujitsuToshibaMobileCommun; IS12T; KDDI)
auのIS12Tという端末です。

2011年12月1日木曜日

[PHP]foreachの参照渡しで見落としがちな事

foreach文で参照渡しをした場合、最後の要素が1つ前の要素と同じ値になっちゃう件です。

$items = array('a','b','c');
foreach($items as &$item){
 echo($item);
}
// --> 'abb'


マニュアルにはちゃんと書いてあるんですけどね。
以下の処理を忘れない事。

unset($item);

2011年11月30日水曜日

[PHP]ディレクトリの再帰削除処理

要件は以下の感じです。

サブフォルダを含めてファイル、ディレクトリを削除する。
ただし、ルートディレクトリは消したくないケースがある。
また、ファイルの最終更新日時が1日以上経ったものだけ削除する。


function rmdirEx($rootPath , $dirDelete){

 if( !is_dir($rootPath)) return;

 $files = scandir($rootPath);

 foreach($files as $file){
  if ($file == '.' || $file == '..') continue;
  $fullpath = $rootPath . DIRECTORY_SEPARATOR . $file;
  if(is_dir($fullpath)){
   rmdirEx($fullpath , true );
  }else{
   $lastUpdateTime = filemtime($fullpath);
   //更新日時が1日以上前のファイルのみ削除する
   if( ($lastUpdateTime + (60 * 60 * 24)) < time())
    @unlink($fullpath);
  }
 }
 //消せれば消す
 if( $dirDelete) @rmdir($rootPath);

}

2011年11月29日火曜日

ajaxuploadを使った。

ブラウザで画像を選択したら、非同期でアップロードして画像を表示したくて使いました。
配布サイトここ(Ajax Upload)

最新版は完全に作り直されたらしくて、「File Upload」って名前に変わってます。
これも色々と試したみたのですが、UI周りのカスタマイズがいまいち分からなかった。

オプション設定で、template、fileTemplate、classesの当たりを設定すれば良さそう何だけど、
ドキュメントも少ないし、心が折れてあきらめました。

その点、旧バージョンのajaxuploadはiframeとか使って怪しいけど、素直で使いやすいです。

$(function(){
 new AjaxUpload('file1', { //input type="file"のid
  action: 'upload.php', //POSTを処理するphp
  name: 'PostName',  //phpで$_FILES['PostName']と使う。
  data: {paramA: 'valueA' ,paramB:'valueB'},  //オプションのデータ。$_POSTで渡される
  onComplete: function(file, response) {   //アップロード完了時のコールバック
   var ret = eval( '(' + response + ')' );  //JSONの展開
   if( ret.success ){
    $('#imageArea').attr('src', ret.path); //イメージの設定
   }
  }
 });

);


PHP側はこんな感じです。

//オプションパラメータの受取
$param = $_POST['paramA'];
$ret = null;
$uploaddir = 'D:\\upload\\';
$filename = basename($_FILES['PostName']['name'])
$uploadfile = $uploaddir . $filename;

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
 $ret = array('success'=>true,'path'=>'/images/' . $filename);
} else {
 $ret = array('success'=>false);
}
echo htmlspecialchars(json_encode($ret), ENT_NOQUOTES);



2011年11月16日水曜日

[ASP]配列の代入は値渡し?参照渡し?

ちょっと久しぶりにASP(classic)を触ったら不安になったので確認しました。
文字列が格納された配列を代入した場合、値渡しでした。


dim a,b,c
a = array("あいう","かきく","さしす")
'代入
b = a

'bの要素を書き換える
b(1) = "けこ"

for each c in a
    response.Write(c & "
") next Response.Write( "
") for each c in b response.Write(c & "
") next

2011年10月27日木曜日

Uploadifyを使った。

複数画像を選択してアップロードする要件があったためUploadifyを使った。
オプション設定も豊富で使いやすいです。

ポップアップウィンドウで使ったのですが、IEではuploader、script、cancelImg、folderのパスを絶対パスで書かないと正常にPOSTされないんですね。

FireFox、Chromeでは相対パスでいけるのに。。。
気が向いたらSafariでも試してみます。


$(document).ready(function() {
$('#file_upload').uploadify({
'uploader' : '/dev/agent/upload/uploadify.swf',
'script' : '/dev/agent/upload/uploadify.php',
'cancelImg' : '/dev/agent/upload/cancel.png',
'folder' : '/dev/images/o_o/',
'auto' : true,
'multi' : true,
'fileExt' : '*.jpg;',
'fileDesc' : 'Image Files (.JPG)',
'queueSizeLimit' : 999 ,
'fileDataName' : 'Filedata' ,
'simUploadLimit' : 1,
'sizeLimit' : 5000000
});
});

2009年11月15日日曜日

[IIS6.0] Webガーデン

IIS6.0導入されたWebガーデンについてのメモです。

Webガーデンで最大ワーカープロセス数を2以上にした場合に注意が必要。
Webガーデンとは、1つのアプリケーションを複数のワーカープロセスで動かす仕組み。
アプリケーション変数や、セッションは共有されない。
つまり、SessionIdは別物になる。
Session領域も別物になる。
システム構築時にクラスタ構成と同じように考慮する必要がある。

あんな簡単に設定できるものが、こんなに大きく影響があってよいのですかねぇ。

2009年11月11日水曜日

[ASP.NET MVC] リストのモデルバインド

ASP.NET MVCでモデルバインドが便利っぽいような不便っぽいような。
新規にリストの値をバインドするなら問題ないのですよ。

Model

Public Class PrivateInfo
Public Name As String
Public History As List(Of History)
End Class

Public Class History
Public eventDate As DateTime
Public Score As Int32
Public Cost As Int32
End Class


View

<%
For each item In Model.History
Dim index As Integer = Model.History.IndexOf(item)
%>
<%=Html.TextBox(String.Format("History[{0}].Score", index), item.Score)%>
<%=Html.TextBox(String.Format("History[{0}].Cost", index), item.Cost)%>

<% Next%>


ところがですね、すでにある程度の値が入っているリストに画面でeventDateを設定させようとしてUpdateModelすると、ScoreとCostが消えちゃうのです。
View

<%
For each item In Model.History
Dim index As Integer = Model.History.IndexOf(item)
%>
<%=Html.TextBox(String.Format("History[{0}].eventDate", index), item.eventDate)%>

<% Next%>


Controller

<AcceptVerbs(HttpVerbs.Post)> _
Public Function Input2(ByVal collection As FormCollection) As ActionResult
Dim model As Models.PrivateInfo = Session("PrivateInfo")

UpdateModel(model)

Return View(model)
End Function



そこまでやってくれないんですね。
対策としては、その他の項目もPostしちゃうと。

View

<%
For each item In Model.History
Dim index As Integer = Model.History.IndexOf(item)
%>
<%=Html.TextBox(String.Format("History[{0}].eventDate", index), item.eventDate)%>
<%=Html.Hidden(String.Format("History[{0}].Score", index), item.Score)%>
<%=Html.Hidden(String.Format("History[{0}].Cost", index), item.Cost)%>

<% Next%>



イケテナイ。
自分でマージするか