Author Archives: admin

viewport覚書

前提知識

デバイスピクセルとCSSピクセル

デバイスピクセルはscreen.widthなどで取得できるもので物理的ピクセルを表す。CSSピクセルはwindow.innerWidthなどで取得できるもので、ズーム値によって異なる。

screen.widthよりもエレメントのwidthが小さければ画面に収まることになる。しかしユーザがズーム機能を使って200%とかにするとそうはならない。ズーム機能はピクセルを広げる機能と考えられるのでCSSピクセルのサイズはズーム値によって異なる。

デバイスピクセルはズームに関わらず常に一定であり、CSSピクセルはデバイスピクセルにズーム率を掛けたものになる(実際は縦横ともにズームされるので平方で掛ける)。

screen.widthはスクリーン全体の幅でデバイスピクセル値なのでブラウザのズーム値では値は変わらないが、window.innerWidthはブラウザウインドウの幅を表しCSSピクセルなのでズーム値によって値が変わる。(ズーム値を100%以下にしていくとwindow.innerWidthのほうがscreen.widthより大きくなることもある)

viewport

画面の狭いスマホではviewportと呼ばれる仮想のウインドウにページをレンダリングし、その後ページをひと目で見れるように全体を縮小する。ユーザはスワイプやズームを使って見たいところにフォーカスする。

これはモバイルに最適化されていないサイトをできるだけ見やすいようにする仕組み

visual viewportとlayout viewport

モバイル端末では画面が小さすぎるので、viewportを2つの概念に分割する。
visual viewportは画面に表示されているページの一部。ユーザはスクロールやズームで表示内容を変えることができる。layout viewportは全体でvisual viewportlayout viewportの一部を表示していることになる。

モバイル端末ではlayout viewportの値は800pxから1000pxくらいになっている。モバイル端末の幅は400pxくらいなので実際よりも大きい値になる。デスクトップではブラウザウィンドウのサイズになっている。

CSSの%で指定されている値はlayout viewportに対して適用される。
モバイル端末のブラウザでは初期表示時は完全にズームアウトされた状態で表示されることが多く、このときは2つのviewportは一致している。

2つのviewportはCSSピクセルで測られ、visual viewportはズームによってサイズが変わる。

document.documentElement.clientWidthlayout viewportの幅を返す。メタタグのviewportがない限り常にこの値は一定であるが、document.documentElement.clientHeightは端末を回転させて縦横が変わると変わる。

window.innerWidthvisual viewportの幅を返す。

viewportメタタグ

viewportメタタグがない場合はサイズ指定なしのエレメントは親のサイズを継承するのでlayout viewportのサイズになる。layout viewportのデフォルトサイズは800px~1000pxだったのでエレメントもそのサイズになり、通常とても小さく表示される。

<meta name="viewport" content="width=320">
この記述があると、layout viewportの幅が320pxになり、最初の表示のときでもエレメントのサイズは320pxになるので小さく表示されない。

まとめ

デスクトップブラウザではviewportはブラウザウィンドウの幅と同じなので気にすることはなかった。モバイル端末ができて、どうやって今までのサイトを表示しようか考えたときにlayout viewportという概念で800pxくらいの全体のサイズを決め打ちして表示するようにした。しかしそれだと表示がとても小さくなってしまうので、メタタグviewportができてここでlayout viewportのサイズを指定できるようにした。

参照

A tale of two viewports — part two
各種のメタタグでサイズを表示するサイト

マウスホイールが回転がたまに逆向きになる

マウスの故障の話。マウスを長期間使っているとホイールを下に回転してるのにたまに上回転になったりして、すごく煩わしいので直したい。

大体の場合はほこりが詰まっているだけだと思うので、分解してほこりを除去すればいいのだが安いマウスの場合、分解したときに固定されていた部品が外れて元に戻すのがすごく大変になったりするので、まずは分解しないで直したい。

dav

やり方はホイールの脇の隙間から軸に向かって狭くて強い空気を送ってほこりを吹き飛ばす。多くの場合右側に軸があると思う。

dav

自分の場合はこれで吹いたらほこりが結構吹き飛んでとりあえず直った感じになった。もしこれがなければストローとかで吹きかければいいと思う。

分解する場合は蓋を外すときに細心の注意を払って部品が吹き飛んだりしないようにして、固定されている部品の状態を維持するようにこころがける。

回復パーティションが2つある

Windowsをアップグレードすると回復パーティションが新たにつくられることがあるそうだ。古い回復パーティションはもう必要ないため削除してもいいらしい

注意:以下の作業はシステムが壊れる可能性があるので自己責任でお願いします。

今使ってる回復パーティションを見つける

管理者権限でコマンドプロンプトを起動しreagentc /infoを実行。

ここから今使ってる回復パーティションはharddisk0\partition3であることがわかる。

回復パーティションを削除する

削除にはDISKPARTを使う。管理者権限でコマンドプロンプトを起動して以下のように行う。

今使っている回復パーティションは3だったのでいらないはずの4を削除した。ディスクの管理でみると以下のようになっている。

あとはこの空いた領域をCドライブと合体させたいので、AOMEI Partition Assistantを使って以下のように行った。

ここで確認を押してツールバーの「適用」を押すと処理が始まる。

完了後の「ディスクの管理」の状態

XPからsambaに接続できない

バージョン確認

直ったやつ

/etc/samba/smb.confに以下を追加。

C言語の標準ライブラリで文字コードの変換

Visual Studioだけで試した。自分用に貼っておく。

C言語とC++のlocale

localeの基本

日付の表示方法は国によって違う。アメリカなら’Friday, July 23, 2021’みたいになり、日本なら’2021/7/23’みたいになる。ほかにも、数字のカンマやピリオドのつけ方や金額表示の仕方もちがう。このような違いを扱うのがlocaleという概念。

catergoryには時刻を扱う。LC_TIMEなどいろいろあるが、ここでは一括で扱うLC_ALLを基本的に考える。

locale文字列は国・地域・言語を表す文字列で、”en-US”などと指定するがプログラム開始時には”C”になっており、”C”は1文字1charであることを意味している。”en-US”などの場合は言語と地域を表しており、さらに追加して”en-US.UTF8″などとも書ける。localeにNULLを渡すと現在の値を取得する。localeに空文字を渡すとユーザのデフォルトの国や地域そしてコードページが指定される。

これを英語のWindowsで実行すると以下のように出力される。

Englishが言語で、United Statesが国・地域、1252がコードページを表しこれは’en-US.1252″と同じ意味だろう。

localeに”.UTF8″とするとコードページだけ変えることができる。ここで指定したコードページはmbtowcsなどでワイド文字列に変換するときに使われる。

C++の場合

上記の話はC言語の話だった。C言語ではlocaleは1つしかなく、グローバル設定があるだけだったが、C++ではlocaleはクラスになった。

C言語との関係

stdにもstd::setlocale()があり、これは上記と同じようにグローバルなlocaleを設定するものだろう。

localeクラス

  • C++ではcategoryの代わりにFacetと言うようになった。
  • C言語ではsetlocal()で設定した情報はグローバルでどこかに格納されそれがアプリコードからは見えないところで参照されるが、C++のストリームでは明示的にlocaleクラスを設定しなければならない

コンストラクタ―

引数のないコンストラクタstd::locale()は、グローバルlocaleクラスのコピーを作成する。

文字列を指定

std::locale("ja-JP")は”ja-JP”のlocaleクラスを作成する。作成しただけではどこにも反映されない。

std::locale::classic();

これはsetlocal(LC_ALL, "C")と同じlocaleのインスタンス参照をかえす。

グローバルに設定

staticなstd::locale::global(locale& l)を呼ぶと、locale lをグローバルに設定する。

ストリームに設定

C++方式でグローバルに設定したlocaleはC言語の関数には影響を与えるがストリームには影響しない。ストリームに反映させるにはimbue()を使って設定する。

Facetとstd::codecvt

省略、facetはbasic_stringのtraitsのように自分で作ることができる、codecvtもfacetの一つ、これは非推奨でなおかつlocaleを使いにくい。globalなlocaleも反映されない。

式の中に出てくるtypenameやtemplate

これらのキーワードは次のトークンがタイプなのかテンプレートなのかを指定する。テンプレート関数内でテンプレート引数Tに依存するトークンが出てきたとき、コンパイラはそのトークンがタイプなのかテンプレートなのか関数なのか変数なのかわからない。

Aが変数なら、例えば0に置き換えてみると以下のようになる。

<や>は小なりと大なりと解釈され、有効な式になる。

Aが関数の場合は<0>はテンプレート引数となりxを引数とする関数コールになる。

Aがテンプレートクラスの場合はそのクラスインスタンスxの定義になる。

テンプレートが実体化されたときにわかりそうだが、意図した動作と違う時にエラーの発見が難しくもなりそうなので、Tに依存するトークンでそれがあいまいな場合(どんな時あいまいなのかはよくわからない)はtypenameやtemplateといったキーワードをつける約束になっているようだ。この例の場合はAはintなどの基本タイプにはなれない。

このような用途で使うのがtypenameとtemplate。

typename

T::Aがタイプの場合に指定する。これはよく使う。意味不明なエラーが出た場合につけると直ることが多い。

template

カギカッコなしのtemplateは他の使い方もあるが、ここではTに依存する(Tの中にある)テンプレートクラスやテンプレート関数を指定するときにつけるようだ。テンプレートクラスの場合はタイプでもあるので、両方つけることもある。

こういうものをつけなければならないときはusingを使って別名にしておいた方がいいだろう。

実験したまとめ

Aが変数の場合

typenanmeもtemplateもつけてはいけない(つけるとエラー)

Aが関数テンプレートの場合

typenameとtemplateと両方つけるか、何もつけない(typenameだけだとエラー)

Aがクラステンプレートの場合

両方つけないとエラー

ソース

https://github.com/ambiesoft/blogprogs/tree/master/6151/templatetypename

参考にした動画