くりーむわーかー

プログラムとか。作ってて ・試しててハマった事など。誰かのお役に立てば幸いかと。 その他、いろいろエトセトラ。。。

2016年10月

jqueryでメニューの外でクリックしたら閉じる

タイトル通り。対象の要素外でクリックした際に対象の要素を消したい場合の書き方。ググればサンプルは一杯出てくると思うけど、2016/10時点で多分一番いいやり方。この手の実装って方法ありすぎて、どれがいいのかわからなくなるのでメモメモ。

$(document).on('click', function (event) {
    if (!$(event.target).closest('.menuClass').length) {
        $('.menuClass').hide();
    }
});

参考にしたとこだと「$(document).on('click touchend', function(event) {」ってやってたけど、自分はclickだけでいいや。

C# enumまわり

もーだめだ。忘れている。メモ。

enumの定義

enum ステータス : int
{
    起票 = 1,
    承認 = 2,
    差戻 = 3,
}

enumの値を繰り返し

foreach (var tmp in Enum.GetValues(typeof(ステータス)))
{
    Console.WriteLine((int)tmp);
}

enumの中身の数値をとるための拡張メソッド

public static class StatusExt
{
	public static int getVal(this ステータス pstatus)
	{
	    return (int)pstatus;
	}
}

文字が割り当てられている外字かどうかを判定する

外字かどうかを判定するというのは結構ある。まー文字のコード範囲がE000~F8FFかどうか見ればいいだけなので、割とすぐ実装できるし、調べればすぐ出てくる。

問題は、文字が割り当てられている外字かどうかを判定しようとしたとき。割り当てられてない文字なんか入ってくるわけないと思いたくなりますが、問題はデータ移行の時。

旧システム、特に他ベンダーから移行するとか、ホストから移行するみたいな場合、外字が入ってるともー発狂したくなる状況に陥りがち。

だいたい、コードの変換表とか作ったりして対応していくと思いますが、それでも変換が間違っていたり色々問題は出てくる。そーゆー時に、外字領域のコードなんだけど、字に割当たってないコードが来た時にどう見つけるかという事です。

字に割当たっていない時は外字のフォントファイルの作られ方によると思うけど、だいたい「・」になる。場合によっては「 」空白だったり、「□」だったりする。字は全部同じ形になるけど、コード的には全部違うので、例えば「”字”=”字”」みたいな比較は不可能。

文字コードで比較できないなら、変換後の字形を比較するしかない。

とゆーことで色々試した結果、↓のコードが出来上がりましたとさ。

とりあえず割り当てられてない文字コードを指定して一文字画像として描画する。あとは調べたいデータの文字を一文字ずつ画像に描画して、画像同士を比較する。比較には画像のハッシュを計算して、それを比較する方法を使用。

とりあえず、比較のベースにする1文字を画像として描画してハッシュを取得。

Encoding unicode = Encoding.GetEncoding("UTF-16");
//比較のベースにする文字コード
short baseChar = Convert.ToInt16("E123", 16);
byte[] baseCharByte = BitConverter.GetBytes(baseChar);
//UTF-16で文字に変える
string baseCharStr = unicode.GetString(baseCharByte);

Font fnt = new Font("MS 明朝", 11);
Bitmap canvasBaseChar = new Bitmap(20, 20);//画像のサイズ
Graphics g = Graphics.FromImage(canvasBaseChar);
g.FillRectangle(Brushes.White, 0, 0, canvasSize, canvasSize);//白で塗りつぶしておく
g.DrawString(baseCharStr, fnt, Brushes.Black, 0, 0);//文字を描画
g.Dispose();

//ベースの文字画像のMD5を取得
BitmapData bmpdata = canvasBaseChar.LockBits(new Rectangle(0, 0, canvasBaseChar.Width, canvasBaseChar.Height), ImageLockMode.ReadWrite, canvasBaseChar.PixelFormat);
IntPtr ptr = bmpdata.Scan0;
int bytes = bmpdata.Stride * canvasBaseChar.Height;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
byte[] baseHash = new MD5CryptoServiceProvider().ComputeHash(rgbValues);

あとはデータの文字列を一文字ずつ同じように画像にしてハッシュを計算してベースと比較する。

Bitmap compareCanvas = new Bitmap(20, 20);
Graphics g = Graphics.FromImage(compareCanvas);
g.FillRectangle(Brushes.White, 0, 0, 20, 20);
g.DrawString(pStr, fnt, Brushes.Black, 0, 0);
g.Dispose();

BitmapData bmpdata = compareCanvas.LockBits(new Rectangle(0, 0, compareCanvas.Width, compareCanvas.Height), ImageLockMode.ReadWrite, compareCanvas.PixelFormat);
IntPtr ptr = bmpdata.Scan0;
int bytes2 = bmpdata.Stride * compareCanvas.Height;
byte[] rgbValues2 = new byte[bytes2];
Marshal.Copy(ptr, rgbValues2, 0, bytes2);
byte[] hash2 = new MD5CryptoServiceProvider().ComputeHash(rgbValues2);

bool bEqual = false;
if (hash2 != null && hash2.Length == baseHash.Length)
{
    int i = 0;
    while ((i < hash2.Length) && (hash2[i] == baseHash[i]))
    {
        i += 1;
    }
    if (i == hash2.Length)
    {
        bEqual = true;
    }
}
if (!bEqual)
{
    Console.WriteLine("違う字形");
}
else
{
    Console.WriteLine("同じ字形");
}

画像のハッシュを計算して比較するロジックはココのブログのロジックを使わせてもらいました。

Webフォントの運用

仕事がらWebサイト上で外字を表示する必要ある。今までは外字の文字を画像とかにして無理くりやってたんだけど、Webフォントがかなり使えそうな感じになってきているので、色々試してみた。サーバはIISで。

IISの場合、デフォルトではWOFFが使えない状態になっているので、MIMEの種類にWOFFを追加する。そしたらWOFFのファイルをサイトに追加して、font-faceの指定とかやる。コレ参照

上記でとりあえず、外字の表示が可能。

で、ここから運用の話。運用する場合は外字ファイルが変わったら自動的に反映(クライアントにも)させたい。 上記のままだとブラウザキャッシュが残るのでF5押して更新しないと反映されない。

CSSの指定で、キャッシュ廃棄させる用のクエリ文字列付けれるかと思いためしたらちゃんと動いた。以下の感じでfont-faecの指定をする。

@font-face {
    font-family: 'EUDC';
    src: url('../fonts/EUDC.woff?20160101') format('woff');
}

ただ、これだとサイトの基本のCSSファイルを必要に応じて書き換える必要があるので、このfont-faceの指定だけ別だしのCSSファイルとしておいた方がいいかな。

あとは.net MVC前提で、Application_Start()とかの中に、フォントファイルの更新日時でクエリ文字列部分を書き換えてCSSを更新するように仕込んでおけば、WOFFをコピペで上書きすれば、自動的に反映されるんじゃなかろうかと愚考してみる(これだとiisresetはいるけど)。

まだ、試してないけど行けそうかな。。。

ただ、最近だとipAmjmっていうフォントファイルがあるんだけど、こいつサイズがでか過ぎるんだよね・・・。いちを国?がいい加減日本語の字形統一すんぞっていう意気込みで作ってるやつっぽいからそのうち全国的に広まるんじゃないかとも思う(かもしれない)。マイナンバーで使おうとしてるらしいし。てか使ってんのかな。

あー、自治体の業務システム的な話です。役所だと人の名前の字形ってすごくシビアなので、どこでも内字(っていう呼び方であってんのかな)にない文字は外字として作成されているわけで。UTF-16のコード範囲でいうと「E000~F8FF」の私用領域の子たち。

今までは自治体毎に外字作ってるんだけど、最近ipAmjmっていうが出始めてきた。で、このフォントファイルでか過ぎてとりあえず、Chromeさんで表示しようとすると「でか過ぎてロードできねーよ」ってブラウザのコンソールに上がってる。。。んーサブセット化したりしないと無理なんだろうか。。。

.net MVC プロジェクト分割

以前、複数のプロジェクトで一つのサイトを構成するエントリを書いた。それの続き。

色々試してみてるけど、とりあえず今のとこ理解した事のメモ。

  • 単純にプロジェクト(ソリューション)分割しても、dllは分かれるけど、アプリケーションプールが分けられない。
  • 上記の場合はSessionの共有ができる。(以前書いたエントリのやり方だと)

個人的にアプリケーションプールも分けたい。ちょろちょろ調べると、アプリケーションプール分けると普通のやり方ではSessionの共有が出来ないっぽい。

基盤的なものを作らないとだめそーですね。ということで、とりあえず、アプリケーションプールも分けられる構成方法は以下。

とりあえず、ベースとなるMVCアプリを作る。(認証系は全部ここに入れるか、別アプリで認証サーバ的な何かを作っておかないとダメ)

で、サブ的なMVCアプリを作る。サブのほうの参照にベースのDLLを入れてコンパイル。

そしたら、Global.asax.csを削除する。して、Global.asaxの編集。以下の感じ。

<%@ Application Codebehind="Global.asax.cs" Inherits="**ここをベースと同じにする**" Language="C#" %>

ここまででベース側の起動処理とかが組み込まれる。逆にサブ側の起動処理的なものはガン無視されるので、不要なファイルは全部消す。

これで全てのサブアプリで共通の基盤的な動きになる。

で、大きな問題が一つ。ルートの定義が出来ない。出来ないというか、Area的なやり方ではないので、.netに組み込まれてる「Html.ActionLink」でサブアプリ側へ行く記述が出来ない。ここはヘルパー自作するしかないかしらね。。。

あと、bundle系。こーゆーのやるなら、もちろんCSSとかスクリプトとかも一か所で管理したいじゃない。。。

困ったことにbundleって”~/hoge/fuga”的な書き方じゃないと許してくれなかった。レイアウトに直書きしかないのかしら。。。ヘルパー作るか?

あと、この構成だと、セッションの共有が出来ないからもちろん認証の共有もデフォじゃ無理。なので、何か仕組みを作っておかないと無理かな。セッションの共有はSQLServerで行けそうだけど微妙かな。。。

さらにためし中。

Chrome エラーが頻発

chromeで「このウェブページの表示中に問題が発生しました」っていうエラーが頻発するようになった。

ちょっと調べると、拡張機能のせいかメモリ不足かユーザープロファイルが壊れたかウィルス対策ソフトかということらしい。

全部やってみたけど効果なし。chrome再インストールとかもしてみたけど効果なし。

で、最近入れたソフトが怪しんだろーなーということで、思い返してみると怪しいやつが確かにいた。

「Microsoft Message Analyzer」←こやつ。

パケットのダンプを解析するMicrosoft純正のツール。ダンプの表示に使ってたんだけど、パケットモニター的な機能もある。このパケットモニター的な機能がめっちゃ怪しい。

ということで、アンインストールしてみたら・・・なおった。

microsoftさんとgoogleさんでケンカしてましたとさ。

みんな仲良うせんとあかんよ。。。

うーむ。他のPCだとこういう症状は出てないから、何か他のやつと抱き合わせで影響するんだろーなー。

問合せ