2010年12月19日日曜日

HTML中のクエリパラメータについて -2-

HTML中のクエリパラメータについて書いたけど
その続き。


html中にあるhref属性にて
クエリ文字列の区切りを「&」としても「&」としても
どっちでもステータスバーには「&」と表示され、
リクエストは「&」で送信されます。


でも、javascriptのlocation.href, replaceなどを使った場合、
ブラウザによって挙動が異なります。


以下のようなコードを書いて実行すると、

location.replace('http://search.yahoo.co.jp/search?p=href+smgl&aq=-1&oq=&ei=UTF-8&fr=top_ga1_sa&x=wrt');



IEの場合

※Internet Explorer 8で実験

 → 「&」が「&」となってリクエストが送信されます。

Firefoxの場合

※Firefox 3.6.12で実験

 → 「&」が「&」のままリクエストが送信されます。


で、HTTPの仕様としてはどうなのだろうと思って調べたけど
どのページを見ていいか分からず...

たぶん「&」が正しいと思うんだけどなー

2010年12月18日土曜日

HTML中のクエリパラメータについて

以下のページにあるように、html中に記述するときは、&ではなくて&

でも、リクエストを送信するときは、ちゃんと&で送信するように!

http://www.ietf.org/rfc/rfc1866.txt


8.2.1. The form-urlencoded Media Type

The default encoding for all forms is `application/x-www-form-
urlencoded'. A form data set is represented in this media type as
follows:

1. The form field names and values are escaped: space
characters are replaced by `+', and then reserved characters
are escaped as per [URL]; that is, non-alphanumeric
characters are replaced by `%HH', a percent sign and two
hexadecimal digits representing the ASCII code of the
character. Line breaks, as in multi-line text field values,
are represented as CR LF pairs, i.e. `%0D%0A'.

2. The fields are listed in the order they appear in the
document with the name separated from the value by `=' and
the pairs separated from each other by `&'. Fields with null
values may be omitted. In particular, unselected radio
buttons and checkboxes should not appear in the encoded
data, but hidden fields with VALUE attributes present
should.


NOTE - The URI from a query form submission can be
used in a normal anchor style hyperlink.
Unfortunately, the use of the `&' character to
separate form fields interacts with its use in SGML
attribute values as an entity reference delimiter.
For example, the URI `http://host/?x=1&y=2' must be
written `<a href="http://host/?x=1&#38;y=2"' or `<a
href="http://host/?x=1&amp;y=2">'.

HTTP server implementors, and in particular, CGI
implementors are encouraged to support the use of
`;' in place of `&' to save users the trouble of
escaping `&' characters this way.

2010年11月22日月曜日

何も書けません...

いろいろ忙しいです。

2010年11月11日木曜日

Mayaa ループ

前回は値の出力(属性への出力も)を実施したので、
今回はループ。

あとは、条件分岐をやれば、だいたいのページは生成できると思います。



さて、こんなテーブルを作りたいことありますよね。

たとえば、一覧出力画面とかで。






で、以下の状況を想定。


  • requestスコープに、listAddressというjava.util.List型のオブジェクトがある

  • Listの中身はPOJOで、customerCode, customerName, customerAddressが存在する



htmlは↓のかんじ






で、mayaaは↓のかんじ






ここでポイントなのが、<m:doBody />タグ。
これがないと、↓のようなhtml出力されてしまいます。






Mayaaのドキュメントには、以下のように書いてあります。


割り当てられたタグのボディを処理します。for プロセッサなどタグのボディが有効なプロセッサで動作します。通常は明示的に使用することはありませんが、Mayaa ファイル側のボディに attribute 以外のプロセッサや空白 (タブ文字、改行を含む) 以外の文字列を記述した場合、doBody を使用しなければタグのボディが処理されません。


つまり、簡単にいうと、forプロセッサのボディを評価したければ、<m:doBody />を書け、と。
この場合だと、を評価しないとinfoが使えませんので、ぜひ<m:doBody />を付けてください。


ちなみに、<m:for />にreplace="false"を付けないと、が消えてしまい、
以下のようなhtmlが出力されてしまいます。



2010年11月9日火曜日

Mayaa 値の挿入

Mayaaについて書いてみる。

まあ、に書いてあるんだけど、
ここには、目的別に書いてみる。


セッション中の値を表示する



●表示




みたいな出力をしたい場合があります。
もちろん、「○○」はセッション中の動的な値で。

そういうときは、

前提

  • セッション中にuserInfoオブジェクトが存在する

  • userInfoにはuserName属性があり、そのgetter/setterが存在する(この場合setterは関係ないかも)

  • ちなみにuserNameはjava.lang.String型である



●html




などと書きます。
もちろん、htmlの先頭には、





と書いておきます。

で、mayaaファイルには




javascript:void(0)
って書けばOKです。


value属性にセッション中の値を表示する



上では要素として?の出力を書きましたが、
属性値に書きたい場合もありますね。

こんな場合を想定↓

●表示は省略。
テキストボックス中のvalueに出力したい場合

1. 想定するケースとしては、入力画面でsubmitしたあと、入力エラーがあって、画面を再表示する場合
2. 変更画面で、現在の値を入力しておいてあげる優しさを見せたいとき


そういうときは、

前提

  • セッション中にuserInfoオブジェクトが存在する

  • userInfoにはuserName属性があり、そのgetter/setterが存在する(この場合setterは関係ないかも)

  • ちなみにuserNameはjava.lang.String型である



●html

変更後のユーザ名:


などと書きます。

で、mayaaファイルには





って書けばOKです。
これで、valueの中に動的な値を出力できます。

2010年11月3日水曜日

Javaテンプレートエンジン [Mayaa]

pythonとか使ってて思うことですが、
強力なテンプレートエンジンがあるってことは
その言語の魅力だなーと。

で、Javaには無いのかーってことで
Mayaa

結構気になってたんだけど
なかなか使う機会なく,,,


ちゃんとドキュメント読んだのは初めてですが、
これはいい!と思ったのはレイアウト。

レイアウト共有

JSPだと、各ページ共通のものをincludeでガチガチ書かないとダメですが、
このレイアウトの発想を待ってました!

要は、基本となるlayout.htmlがあって、
各ページで異なる部分をそこにインサートしていく、と。


詳細は次回。

2010年10月31日日曜日

OAuth Examples (Python) を読んでみる

OAuthが必要になったので勉強してます。
とりあえず、Google先生に聞いて概要は理解したけど
ソースを読まないことにはなんともならん、と。

で、

OAuth Examples

を読んでみた。
Pythonなので、
AppEngine-OAuth-Library by Mike Knapp (more)
ってところです。


OAuthの流れ。
自サイトとTwitter連携の話。

 Consumerは自サイト
 Service ProviderはTwitter
Userはあなた

twt-tnkというサイトを作りました。

これが自サイトとします。





0.ConsumerはService ProviderからあらかじめOAuth利用許可を得る

このステップは,具体的にはService ProviderにConsumer登録を行い,Consumer KeyとConsumer Secretという値を取得することで行います。
これは、事前の登録で、Twitterにそのページがあります。


開発者
連携アプリの追加と設定はこちらから変更できます。


ってところです。


1.UserがConsumerに,Service Providerから認可が必要な情報へのアクセス権を取得するように指示する。

自サイトにある「Twitterにログイン」的なリンクを用意し、それをUserが押す行為です。

twt-tnk画面上部に「Twitterアカウントでログインする 」ってのがあり、
「/login」というURLになってます。


2.ConsumerはバックグラウンドでService Providerにアクセスし,未認可のRequest Tokenを取得する

自サイトがバックグラウンドでTwitterにアクセスし、未認可のRequest Tokenを取得します。

def get(self, mode=""):

#TwitterClient、Cookiesクラスの作成
(client, cookie) = CreateClientAndCookie(self)

#Twitterの認証画面表示
if mode == "login":
#Twitterの認証画面へリダイレクトする
return self.redirect(client.get_authorization_url())

def CreateClientAndCookie(self):

#Twitter認証画面からのコールバック用URLを設定
callback_url = "%s/verify" % self.request.host_url

#TwitterClientクラスの作成
client = oauth.TwitterClient(CONSUMER_KEY, CONSUMER_SECRET,
callback_url)
#Cookiesクラスの作成
cookie = Cookies(self, max_age=COOKIE_EXPIRE_TIME)

return client, cookie




3.ConsumerはUserをService Providerにリダイレクトさせる。この際Consumerは未認可のRequest TokenをURL Parameterに付加する

自サイトはUserをTwitterにリダイレクトさせます。Request TokenをGETパラメータに付与して。

上のソースを見ると、loginときたら、すぐにself.redirect(client.get_authorization_url())としていますが、

実は、client.get_authorization_url() の中でちゃんとTwitterにアクセスしてRequest Tokenを取得しています。
自サイトの「Twitterアカウントでログインする」を押すと、ちゃんと
http://twitter.com/oauth/authorize?oauth_token=
にアクセスしているのがブラウザ上で分かります。


def get_authorization_url(self):
"""Get Authorization URL."""

token = self._get_auth_token()
return "http://twitter.com/oauth/authorize?oauth_token=%s" % token

def _get_auth_token(self):
"""Get Authorization Token.

Actually gets the authorization token and secret from the service. The
token and secret are stored in our database, and the auth token is
returned.
"""

response = self.make_request(self.request_url)
result = self._extract_credentials(response)

auth_token = result["token"]
auth_secret = result["secret"]

# Save the auth token and secret in our database.
auth = AuthToken(service=self.service_name,
token=auth_token,
secret=auth_secret)
auth.put()

# Add the secret to memcache as well.
memcache.set(self._get_memcache_auth_key(auth_token), auth_secret,
time=20*60)

return auth_token



ちなみに、TwitterClientはこんなかんじ。

class TwitterClient(OAuthClient):
"""Twitter Client.

A client for talking to the Twitter API using OAuth as the
authentication model.
"""

def __init__(self, consumer_key, consumer_secret, callback_url):
"""Constructor."""

OAuthClient.__init__(self,
"twitter",
consumer_key,
consumer_secret,
"http://twitter.com/oauth/request_token",
"http://twitter.com/oauth/access_token",
callback_url)


ちなみにちなみに、バックグラウンドでリクエスト送ってる箇所は↓のかんじ


def make_async_request(self, url, token="", secret="", additional_params=None,
protected=False, method=urlfetch.GET):
"""Make Request.

Make an authenticated request to any OAuth protected resource.

If protected is equal to True, the Authorization: OAuth header will be set.

A urlfetch response object is returned.
"""
payload = self.prepare_request(url, token, secret, additional_params,
method)
if method == urlfetch.GET:
url = "%s?%s" % (url, payload)
payload = None
headers = {"Authorization": "OAuth"} if protected else {}
rpc = urlfetch.create_rpc(deadline=10.0)
urlfetch.make_fetch_call(rpc, url, method=method, headers=headers, payload=payload)
return rpc

def make_request(self, url, token="", secret="", additional_params=None,
protected=False, method=urlfetch.GET):
return self.make_async_request(url, token, secret, additional_params, protected, method).get_result()




4.UserはService Provider上でConsumerへのアクセス権委譲を許可する。この際Service Providerは未認可のRequest Tokenを認可済とする

Userは、Twitterのページで、「許可する」といったボタンを押下し、アクセス権委譲を許可します。
すると、TwitterはRequest Tokenを認可済としてくれます。




5.Service ProviderはUserをConsumerにリダイレクトさせる。この際Service Providerは認可済のRequest TokenをURLに含める

TwitterはUserを自サイトにリダイレクトしてくれます。
このとき、GETパラメータに認可済みのRequest Tokenが付与されてます。


6.ConsumerはバックグラウンドでService Providerと通信を行い,認可済のRequest Tokenを実際のアクセス権を示すAccess Tokenと交換する

自サイトはバックグラウンドでTwitterと通信を行い、認可済のRequest TokenをAccess Tokenと交換してもらいます。

リダイレクトされたら、自サイトは以下の処理をします。


#-----------------------------------------------------------
#OAuthの認証後に、アクセストークンをCookieに保存
#-----------------------------------------------------------
def VerityAuth(self, client, cookie):
auth_token = self.request.get("oauth_token")
auth_verifier = self.request.get("oauth_verifier")
user_info = client.get_user_info(auth_token, auth_verifier=auth_verifier)

#アクセストークンをCookieへ保存
cookie["user_token"] = user_info["token"]
cookie["user_secret"] = user_info["secret"]
cookie["screen_name"] = user_info["username"]


client.get_user_info(auth_token, auth_verifier=auth_verifier)で、認可済のRequest TokenをAccess Tokenと交換してもらっています。


def get_user_info(self, auth_token, auth_verifier=""):
"""Get User Info.

Exchanges the auth token for an access token and returns a dictionary
of information about the authenticated user.
"""

auth_token = urlunquote(auth_token)
auth_verifier = urlunquote(auth_verifier)

auth_secret = memcache.get(self._get_memcache_auth_key(auth_token))

if not auth_secret:
result = AuthToken.gql("""
WHERE
service = :1 AND
token = :2
LIMIT
1
""", self.service_name, auth_token).get()

if not result:
logging.error("The auth token %s was not found in our db" % auth_token)
raise Exception, "Could not find Auth Token in database"
else:
auth_secret = result.secret

response = self.make_request(self.access_url,
token=auth_token,
secret=auth_secret,
additional_params={"oauth_verifier":
auth_verifier})

# Extract the access token/secret from the response.
result = self._extract_credentials(response)

# Try to collect some information about this user from the service.
user_info = self._lookup_user_info(result["token"], result["secret"])
user_info.update(result)

return user_info



7.Consumerは6)で得られたTokenを利用して,特定の情報にアクセスする


その他のメソッドなど。

def _get_memcache_auth_key(self, auth_token):

return "oauth_%s_%s" % (self.service_name, auth_token)

def _extract_credentials(self, result):
"""Extract Credentials.

Returns an dictionary containing the token and secret (if present).
Throws an Exception otherwise.
"""

token = None
secret = None
parsed_results = parse_qs(result.content)

if "oauth_token" in parsed_results:
token = parsed_results["oauth_token"][0]

if "oauth_token_secret" in parsed_results:
secret = parsed_results["oauth_token_secret"][0]

if not (token and secret) or result.status_code != 200:
logging.error("Could not extract token/secret: %s" % result.content)
raise OAuthException("Problem talking to the service")

return {
"service": self.service_name,
"token": token,
"secret": secret
}



Twitterからもらえるuser_infoは↓のかんじ

def _lookup_user_info(self, access_token, access_secret):
"""Lookup User Info.

Lookup the user on Twitter.
"""

response = self.make_request(
"http://twitter.com/account/verify_credentials.json",
token=access_token, secret=access_secret, protected=True)

data = json.loads(response.content)

user_info = self._get_default_user_info()
user_info["id"] = data["id"]
user_info["username"] = data["screen_name"]
user_info["name"] = data["name"]
user_info["picture"] = data["profile_image_url"]

return user_info

2010年10月17日日曜日

phpを始める

phpを始める。
目指せ!phpの資格!!

apacheのダウンロード
Windowsで開発します
apache windows binary [Download]

eclipseのダウンロード
開発環境はeclipse + pluginで。
pleiades eclipse 3.6 [Download]

参考書
やっぱオライリーでしょうか
プログラミングPHP 第2版

php
Windows用のphp
php5.3
php

2010年10月8日金曜日

jTemplatesを使ってみる

ajaxでの通信後、HTML表示が面倒だなーと思ってたら、↓を発見。
業界的には気づくの遅いか??

jTemplates

javascript内に書いたり、
HTMLコメントとして書いたり、
いろいろできるっぽいけど
テンプレートファイルに書き出すのがスマートっぽい。

テンプレートファイル


templateフォルダにsample.tplとか置いてみる。





JavaScript


jqueryと一緒に読み込んで、$(document).readyで書いてみる。
ちなみにjqueryは1.4.2






なんとまあ便利なんだろうか!!

2010年9月26日日曜日

GAE -テキストファイル出力-

↓のかんじ。
入力内容をファイルで出力するだけ。

ローカルだと日本語ファイル名できたけど、
デプロイしたらNGっぽくなった、、、、



'attachment;filename="' + filename.encode('utf-8') + '"'


ここがNGなんだと思うけど、
文字コードは何にすればいいのか??





class TextDownload(webapp.RequestHandler):
def post(self):
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
login = True
user_name = users.get_current_user().nickname()
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
login = False
user_name = 'anonymous'

text = self.request.get('filebody')
filename = self.request.get('filename')
if filename == '':
filename = 'notitle.txt'

self.response.headers['content-type'] = "application/octet-stream; charset=utf-8"
self.response.headers['Content-disposition'] = 'attachment;filename="' + filename.encode('utf-8') + '"'
self.response.out.write(cgi.escape(text))

2010年9月24日金曜日

デザインに凝ってみた

特に中身を変更したわけではないですが、テンプレートの使い方とか
pythonでのTrue, Falseとか覚えました。

Trueって書かないと駄目なんですね。
trueじゃ。

あと、

!変数

もだめで、

not 変数

なんですね。
勉強になります。

2010年9月23日木曜日

GAE メール送信成功!

GAEのサンプルにあるguestbookにメール送信機能をつけてみた。

●機能


ログインして書き込むとログインしているユーザ宛てに書き込んだ内容が送信される


使ってみたけど、結構無駄機能?
量が多いとちょっとウザイかも。

↓こんなかんじ

if users.get_current_user():
sender_address = users.get_current_user().email()
subject = "GuestBook is Updated"
body = "[%s] %s" % (greeting.date, self.request.get('content'))
mail.send_mail(sender_address, greeting.author.email(), subject, body)

gae and python at eclipse

まず、python2.5をアップデートしました。
2.5.2 → 2.5.4

2.5.4

インストールしたら、なぜか2.5.2が消えました。

!!!

続いてpydevは、updateサイトだとエラーが出てしまったので
仕方なくzipを解凍して置きました。

 pydev at sourceforge


インストール終わったので、eclipse起動。

新規→「その他」→「PyDev Google App Engine Project」

でプロジェクト作成。

pythonは忘れずにインストールした2.5.4を指定。

さて、これから頑張ってみます。

GAE再び

Androidアプリを作るにしても
Webサービスとの連携しなくては!と思ったので
GAE再開です。

Javaプログラマですが、
ここは何とかPythonでやってみようと思います。


ユーザーサービスの利用


pythonを複数バージョン入れてたらエラーが出だした、、、



pythonを2.5だけにして2.7をアンインストールしたら動いた。
環境変数指定してるのに不思議だなー

2010年9月6日月曜日

オライリーで頑張ってます|3章

オライリーの本買って、それで勉強してます。
「初めてのandoroid」


今日までで、aboutの表示まで完成しました。

まずは初期画面。
一応、日本語にしてみました。





でで、ヘルプっていうのを押したときの画面も。




ヘルプの内容を訳すのが面倒だった、、、、

2010年9月4日土曜日

Android SDK with Xperia

そにーえりくそんのページから
Xperiaのskinを入手できる。

いま一番のandroidインJAPANなので
これで作りたいと思い、以下のページから入手

ここから入手


ログインが必要ということでしたが、
アカウントなくても入手できました!!

ダウンロードしたファイル「102216-XPERIA-X10_SDK_Add-on_r1.zip」
を解凍して出てきたフォルダ「XPERIA-X10_r1」を丸ごと移動。

移動先は、androidをインストールした場所のadd-onsフォルダ内。
私はandroidを「C:\opt\android\android-sdk-windows」に入れたので、

「C:\opt\android\android-sdk-windows\add-ons」に入れて
「C:\opt\android\android-sdk-windows\add-ons\XPERIA-X10_r1」
となりました。

あとは、Eclipseだと楽勝ですね。

Window→Android SDK and AVD Manager→Virtual Devices

新規(New)から

名前はXperia
ターゲットはX10(Sony Ericsson Mobile Communications)
SDカードは100でいいかな

2010年8月12日木曜日

python

いろいろと言語を勉強してみたくなった。
まずはPHPと思ったけど
早速Pythonに変更!

●開発環境はeclipse with pydev




●python自体は公式サイトからWindows版インストーラをゲット



このファイルをゲットしました → python-2.7.msi

●インストール場所は

C:\usr\local\python

にバージョンごとに入れることにしました。
↓こんなかんじ

C:\usr\local\python\python27\

●ついでにjythonもゲット
↓から、jython_installer-2.5.1.jarをゲット




例によって、C:\usr\local\jythonに入れます。


eclipseを起動して、設定からPydevのインタープリタを今回入れたものにしました。
最初からpython入ってるけど、それは削除。
バージョンわからんし。

2010年6月29日火曜日

Android SDK

Android SDKを入れてみた。

1. ダウンロード

<http://developer.android.com/sdk/index.html> からダウンロードしました。
android-sdk_r06-windows.zip です。

2. 解凍

上記zipを解凍して、C:\opt\android\android-sdk-windows としました。

3. パスの設定

ANDROID_HOME=C:\opt\android\android-sdk-windowsとして、
Pathに%ANDROID_HOME%\tools を追加しました。

4. インストール

C:\opt\android\android-sdk-windows にあるSDK Setup.exeをダブルクリックするが、


Failed to fetch URL https://dl-ssl.google.com/android/repository/repository.xml,
reason: HTTPS SSL error.
You might want to force download through HTTP in the settings.


とか出るので、以下を実施
C:\opt\android\android-sdk-windows\tools に.androidフォルダが出来ているので、
そこにandroidtool.cfg というファイルを作って、


sdkman.force.http=true


と書きます。
んで、再チャレンジ!



2010年4月2日金曜日

Seleniumの証跡をHTMLソースで

Selenium好きです。

でも、まあ、画面証跡だとdiffを取るのが難しいですよね。

で、HTMLで証跡を取りたいのですが、

なかなか難しい。

拡張スクリプトでも作ろうかと思いましたが、

JavaScriptでの保存は難しかった。

そこで、アドオンを利用することを思いついた。
以下のサイトの応用を考えたのです!

[Test]Seleniumでキャプチャを取得する拡張コマンド:captureScreenshot


つまり、HTMLを取得するアドオンをインストールし、
ショートカットキーを使えばいいと。


で、ありました。

ScrapBook


これ入れると、

Ctrl + Shift + L


でHTMLを保存できます。

Selenium的には、以下のコマンドを挿入すれば大丈夫です。
ポイントはshiftKeyUpとcontrolKeyUpです。

★これをやらないと、typeコマンドでエラーがでてしまいます。


<tr>
    <td>controlKeyDown</td>
    <td></td>
    <td></td>
</tr>
<tr>
    <td>shiftKeyDown</td>
    <td></td>
    <td></td>
</tr>
<tr>
    <td>keyPress</td>
    <td>//body</td>
    <td>76</td>
</tr>
<tr>
    <td>controlKeyUp</td>
    <td></td>
    <td></td>
</tr>
<tr>
    <td>shiftKeyUp</td>
    <td></td>
    <td></td>
</tr>


で、最後にScrapBookの設定です。

ツールバーにある「ScrapBook」から「サイドバーに表示」をクリックし、
「ツール」→「設定」→「詳細」から
”取り込みが完了したら通知する”をOFFにしてください。


あと問題なのは、全HTMLファイル、画像等を取得してくれるのですが、
ファイル名が全部index.htmlであることでしょうか。。。



以上でございます。

2010年4月1日木曜日

続いて

Rubyの思想とか、
だいたいの文法とか勉強しました。

で、あまり向いてなさそうだったので、
もうしばらくJavaで行こうと思います。

そんで、以下のものに手を出しました。


  1. play!

  2. mayaa



play!はRuby on Railsの思想で簡単構築を目指したので。

mayaaはJSP嫌いなので。
JSPとも親和性あるので、他よりは導入が気楽そう。
(他が何を指すか不明ですが。。。)

2010年2月27日土曜日

Ruby: 線形探索法組んでみた

線形探索法をRubyで実装してみた。
配列[5, 2, 1, 3, 4]からanswer=3を探索するプログラム。
if文の書き方に手間取った。
あと、型を書かなくていいってことに戸惑った。
whileじゃなくて、eachとかでも良かったのかな?
繰り返しの実装方法も慣れない。

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
array = [5, 2, 1, 3, 4];

index = 0;
answer = 3;
array[5] = 1;

while index < array.length
if array[index] == answer then
break
else
index = index + 1
end
end

if index < array.length - 1 then
print "success, answer=array[", index, "]:", array[index]
else
print "failure";
end
〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

2010年2月10日水曜日

Ruby

Ruby始めました。

2010年1月30日土曜日

ウィンドウ名の取得

あんまり使わないと思ってたけど
意外と使う機会があった。
ウィンドウ名の取得






メインウィンドウでない場合は、サイズを変えたいとか。
まあ、画面の使いまわし。
そういうの好きじゃないけど、
最後の最後ってとこで使えそう。

2010年1月15日金曜日