2009年6月アーカイブ

Qt4 自前のsignalの作り方

自分勝手な sugnal の定義方のメモ

例:フォーカスを持ったボタンでキーが押されたときにシグナルを発生させる。

(1) シグナルのセクションを用意する。
signals: というのを class の中に追加。
public、private、protected のどれでもいいのか?
内容的には private か protected だろうな。

(2) シグナルとなるメソッドを追加する。
void signal_key_pressed( int ); としてみた。
シグナルには引数をつけることができる。
押されたキーを引数に渡すことをもくろみ int にしてみる。

(3) シグナルを発生させる処理を実装する。
virtual void keyPressEvent(QKeyEvent *event) をオーバーライドし、
emit signal_key_pressed( event->key() );
でシグナルを発生させる。

(4) シグナル受け取る側のスロットを用意する。
セクション slots: を追加。

(5) スロットのメソッドを宣言する。
void slot_key_pressed(int) とした。

(6) QObject::connect() を用いてスロットにつなぐ。

(7) スロットを実装する。


--- シグナルを送るクラス
class someButton : public QPushButton
{
    Q_OBJECT

private:
    void _init() {  ... }

public:
    someButton (QWidget * parent =0) : QPushButton(parent) {
        _init();
        ...
    }
    ~someButton () { ... };

signals:	// (1)
    void signal_key_pressed( int );	// (2)

protected:
    virtual void keyPressEvent(QKeyEvent *event) {
        emit signal_key_pressed( event->key() );	// (3)
    }
};

--- シグナルを受けるクラス
class someWidget : public QWidget
{
    Q_OBJECT

public:
    someWidget (QWidget *parent = 0)   : QWidget(parent) {
        _init(this);
        ....
    }
    ~someWidget () {}

    someButton* button;

private:
    void _init() {
        button = new someButton();
        QObject::connect(button,SIGNAL(signal_key_pressed(int)),
            this, SLOT(slot_key_pressed(int)));	// (6)
    }

private slots:	// (4)
    void slot_key_pressed(int);	// (5)
}

void someWidget::slot_key_pressed(int key)	// (7)
{
    switch(key)
    {
    ...
    }
}

メールアドレス javaScript

メールアドレスを自動収集から隠すスクリプト。
どのくらい効果あるか不明。
参考:http://www.projecthoneypot.org/how_to_avoid_spambots_3.php

<div class="widget-contant widget">
<script type='text/javascript'>
var c = Array('<','/','a','>');
var d = Array('g','m','a','i','l')
var j = Array('@',':','.');
var n = Array('to','ka','c','hi','.','l','ab' );
var o = Array('<','a',' ','h','r','e','f','=','"','>');
var t = Array('c','o','m');
var u = Array('m','a','i','l','t','o');

function f1() {
	for (i=0; i<n.length;  i++) { document.write(n[i]); }
	for (i=0; i<j.length-2;i++) { document.write(j[i]); }
	for (i=0; i<d.length;  i++) { document.write(d[i]); }
	for (i=2; i<j.length;  i++) { document.write(j[i]); }
	for (i=0; i<t.length;  i++) { document.write(t[i]); }
}
function f2() {
	for (i=0; i<u.length;  i++) { document.write(u[i]); }
	for (i=1; i<j.length-1;i++) { document.write(j[i]); }
	f1();
}

function f() {
	for (i=0; i<o.length-1; i++) { document.write(o[i]); }
	f2();
	for (i=o.length-2; i<o.length;i++) { document.write(o[i]); }
	f1();
	for (i=0; i<c.length; i++) { document.write(c[i]); }
}
</script>

<h3 class="widget-header">連絡先</h3>
<div class="widget-content">
<script type='text/javascript'>f();</script>
</div>
</div>

連絡先

sudoku

数独のソース

用意するもの、
Eclispe
CDT
Qt4
Qt4 Eclipse Integration
ソースとバイナリ http://cid-e844b718ee02a287.skydrive.live.com/self.aspx/.Public/examples/sudoku.zip

[main.cpp]

#include "qs2.h" #include <QtGui> #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); QsudokuClass w; w.show(); return a.exec(); }

[qs2.h]

#ifndef QS2_H #define QS2_H #include <QtCore/QVariant> #include <QtGui/QAction> #include <QtGui/QApplication> #include <QtGui/QButtonGroup> #include <QtGui/QGridLayout> #include <QtGui/QHeaderView> #include <QtGui/QPushButton> #include <QtGui/QWidget> #include <QKeyEvent> #include <QThread> #include "ui_qs2.h" class sudokuCell : public QPushButton { private: void _init() { num = 0; QSizePolicy policy(QSizePolicy::Minimum, QSizePolicy::Minimum); policy.setHorizontalStretch(0); policy.setVerticalStretch(0); policy.setHeightForWidth( this->sizePolicy().hasHeightForWidth()); this->setSizePolicy(policy); this->setMaximumSize(QSize(35, 35)); this->setFlat(false); this->setCheckable(true); } public: int num; char label[8]; sudokuCell(QWidget * parent =0) : QPushButton(parent) { _init(); } sudokuCell(const QString & text, QWidget * parent = 0) : QPushButton(text, parent) { _init(); } sudokuCell(const QIcon & icon, const QString & text, QWidget * parent = 0 ) : QPushButton(icon, text, parent) { _init(); } ~sudokuCell() {}; int Number (void) { return num; } void Number (int new_num) { num = new_num; } void Display(int num =-1) { label[0] = 0; if (num<0) num = this->num; if (num) sprintf(label, "%d", num); setText(label); } protected: virtual void keyPressEvent(QKeyEvent *event) { int key; switch (event->key()) { case Qt::Key_Left: key = Qt::Key_S; break; case Qt::Key_Right: key = Qt::Key_D; break; case Qt::Key_Up: key = Qt::Key_E; break; case Qt::Key_Down: key = Qt::Key_X; break; case Qt::Key_Space: key = Qt::Key_0; break; default: key = event->key(); break; } QApplication::postEvent(parentWidget(), new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier)); }; }; class QKeyEvent; class QsudokuClass : public QWidget { Q_OBJECT int x; int y; bool cancel; public: QWidget *gridLayoutWidget; QGridLayout *gridLayout; sudokuCell *cell[9][9]; bool chk[9][9]; QThread *probe; QsudokuClass(QWidget *parent = 0) : QWidget(parent) { setupUi(this); x = -1; y = -1; for (int i=0; i<9; i++) for (int j=0; j<9; j++) chk[i][j] = 0; } ~QsudokuClass() {} void Number (int num) { if (x >= 0 && y >= 0) cell[y][x]->Number(num); } int Number (void) { return (x >= 0 && y >= 0) ? cell[y][x]->Number() : -1; } void Display(int v, int h, int num =-1) { cell[v][h]->Display(num); } void Display(); void emuClick(int x, int y); void setupUi(QWidget *widget) { if (widget->objectName().isEmpty()) widget->setObjectName(QString::fromUtf8("QsudokuClass")); widget->resize(350, 350); gridLayoutWidget = new QWidget(widget); gridLayoutWidget->setObjectName( QString::fromUtf8("gridLayoutWidget")); gridLayoutWidget->setGeometry(QRect(5, 5, 340, 340)); gridLayout = new QGridLayout(gridLayoutWidget); gridLayout->setSpacing(1); gridLayout->setMargin(1); gridLayout->setObjectName(QString::fromUtf8("gridLayout")); gridLayout->setSizeConstraint(QLayout::SetDefaultConstraint); gridLayout->setContentsMargins(0, 0, 0, 0); widget->setWindowTitle(QApplication::translate("QsudokuClass", "Sudoku?", 0, QApplication::UnicodeUTF8)); for (int y=0; y<9; y++) { for (int x=0; x<9; x++) { QString name,label; name.sprintf("CELL_%d%d",y,x); cell[y][x] = new sudokuCell(name,gridLayoutWidget); cell[y][x]->setText(""); gridLayout->addWidget(cell[y][x], y, x, 1, 1); QObject::connect(cell[y][x], SIGNAL(clicked()), widget, SLOT(sel_change())); } } QMetaObject::connectSlotsByName(widget); probe = NULL; } private: // Ui::QS2Class ui; private slots: void sel_change(); protected: virtual void keyPressEvent(QKeyEvent *event); }; #endif // QS2_H

[qs2.cpp]

#include "qs2.h" #include "sudokuThread.h" void QsudokuClass::sel_change() { if (x > -1 && y > -1) cell[y][x]->setChecked(false); for (int i=0; i<9; i++) for (int j=0; j<9; j++) if (cell[i][j]->isChecked()) { x = j; y = i; Display(i,j); } } void QsudokuClass::Display() { bool complete = (probe) ? ((sudokuThread*)probe)->complete:false; for (int i=0; i<9; i++) for (int j=0; j<9; j++) { QFont font; if (complete || chk[i][j]) { font.setPointSize(12); font.setBold(true); } else { font.setPointSize(8); font.setBold(false); } cell[i][j]->setFont(font); cell[i][j]->Display(); } } void QsudokuClass::emuClick(int h, int v) { cell[v][h]->setChecked(true); sel_change(); } void QsudokuClass::keyPressEvent(QKeyEvent *event) { if (x < 0 || y < 0) return; switch (event->key()) { case Qt::Key_Space: cell[y][x]->Number(0); break; case Qt::Key_0: cell[y][x]->Number(0); break; case Qt::Key_1: cell[y][x]->Number(1); break; case Qt::Key_2: cell[y][x]->Number(2); break; case Qt::Key_3: cell[y][x]->Number(3); break; case Qt::Key_4: cell[y][x]->Number(4); break; case Qt::Key_5: cell[y][x]->Number(5); break; case Qt::Key_6: cell[y][x]->Number(6); break; case Qt::Key_7: cell[y][x]->Number(7); break; case Qt::Key_8: cell[y][x]->Number(8); break; case Qt::Key_9: cell[y][x]->Number(9); break; case Qt::Key_S: emuClick((x+8)%9,y); return; case Qt::Key_D: emuClick((x+1)%9,y); return; case Qt::Key_E: emuClick(x,(y+8)%9); return; case Qt::Key_X: emuClick(x,(y+1)%9); return; case Qt::Key_R: Display(); return; default: { int dummy; dummy = 0; } return; } chk[y][x] = cell[y][x]->Number(); if (probe) { ((sudokuThread*)probe)->cancel(); probe->terminate(); delete probe; probe = NULL; } for (int i=0; i<9; i++) for (int j=0; j<9; j++) if (!chk[i][j]) cell[i][j]->Number(0); Display(); probe = new sudokuThread(this); probe->start(); }

[sudokThread.h]

/* * sudokuThread.h * * Created on: 2009/06/25 * Author: Tenshi */ #ifndef SUDOKUTHREAD_H_ #define SUDOKUTHREAD_H_ #include "qs2.h" class sudokuThread : public QThread { Q_OBJECT protected: QsudokuClass* sudoku; int num(int v, int h) { return (sudoku) ? sudoku->cell[v][h]->Number() : -1; } void setNum(int v, int h, int num) { if (!sudoku) return; else sudoku->cell[v][h]->Number(num); } void probe(int loc); void run() { while (!cancel_flag) { ans = 0; probe(0); if (ans == 1) { complete = true; wait(); } } exit (); } public: int ans; bool complete; bool cancel_flag; sudokuThread(QObject *parent = 0) { sudoku = (QsudokuClass*)parent; cancel_flag = false; complete = false; } virtual ~sudokuThread() { } void cancel() { cancel_flag = true; } }; #endif /* SUDOKUTHREAD_H_ */

[sudokuThread.cpp]

/* * sudokuThread.cpp * * Created on: 2009/06/25 * Author: Tenshi */ #include "ui_qs2.h" #include "sudokuThread.h" void sudokuThread::probe(int loc) { if (cancel_flag) return; if (loc==81) { ans ++; QApplication::postEvent(sudoku, new QKeyEvent(QEvent::KeyPress, Qt::Key_R, Qt::NoModifier)); msleep(300); } else { int x = loc % 9; int y = loc / 9; int bx = (x/3)*3; int by = (y/3)*3; if (num(y,x)!=0) { probe(loc+1); } else { for (int n=1; n<=9; n++) { bool used = false; int ix,iy; for (ix=0; !used && ix<9; ix++) if (num(y,ix)==n) used=true; for (iy=0; !used && iy<9; iy++) if (num(iy,x)==n) used=true; for (iy=by; !used && iy<by+3; iy++) for (ix=bx; !used && ix<bx+3; ix++) if (num(iy,ix)==n) used=true; if (used) continue; setNum(y,x,n); probe(loc+1); setNum(y,x,0); } } } }

以前つくった OpenOffice.org のフォーム用の Windows専用IMM 制御マクロを 
Vista + ATOK で使ってみたら、全角入力にした EDIT ボックスが「かな入力」に
なってしまうことを発見。対策としてコードの一部を変更。

具体的には imm コントロールのフラグを IME_CMODE_JAPANESE と
IME_CMODE_FULLSHAPE に加えて IME_CMODE_ROMAN も指定するようにしました。

MS-IME で使っているなら変更の必要はありません。
「ローマ字」より「かな入力」が得意な人はそのままでお使いください。

REM  *****  BASIC  *****

Option Explicit

const SYSTEM_WIN32 as long        = 1
const SYSTEM_WIN16 as long        = 2
const SYSTEM_JAVA as long           = 3
const SYSTEM_OS2 as long            = 4
const SYSTEM_MAC as long            = 5
const SYSTEM_XWINDOW as long  = 6

Declare Function ImmCreateContext        Lib "imm32.dll" () as long
Declare Function ImmAssociateContext    Lib "imm32.dll" (ByVal hWnd as long, ByVal hIMC as long) as long
Declare Function ImmDestroyContext        Lib "imm32.dll" (ByVal hIMC as long) as long
Declare Function ImmGetContext            Lib "imm32.dll" (ByVal hWnd as long) as long
Declare Function ImmReleaseContext        Lib "imm32.dll" (ByVal hWnd as long, ByVal hIMC as long) as long
Declare Function ImmSetOpenStatus        Lib "imm32.dll" (ByVal hIMC as long, ByVal bOpen as long) as long
Declare Function ImmGetOpenStatus        Lib "imm32.dll" (ByVal hIMC as long)  as long
Declare Function ImmGetConversionStatus    Lib "imm32.dll" (ByVal hIMC as long, cmode as long, smode as long) as long
Declare Function ImmSetConversionStatus    Lib "imm32.dll" (ByVal hIMC as long, ByVal cmode as long, ByVal smode as long) as long
Declare Function ImmGetDefaultIMEWnd        Lib "imm32.dll" (ByVal hWnd as long) as long

Global const IME_CMODE_ALPHANUMERIC        as long    = 0        ' アルファベット
Global const IME_CMODE_NATIVE            as long    = 1        ' 日本語(各国語)
Global const IME_CMODE_JAPANESE            as long    = 1        ' = IME_CMODE_NATIVE
Global const IME_CMODE_KATAKANA            as long    = 2        ' カタカナ/ひらかな
Global const IME_CMODE_LANGUAGE            as long    = 3        ' 言語マスク?
Global const IME_CMODE_FULLSHAPE        as long    = &h008    ' 全角/半角
Global const IME_CMODE_ROMAN            as long    = &h010    ' ローマ字入力
Global const IME_CMODE_CHARCODE            as long    = &h020    ' コード入力
Global const IME_CMODE_HANJACONVERT        as long    = &h040    '
Global const IME_CMODE_SOFTKBD            as long    = &h080    ' ソフトウェアキーボード
Global const IME_CMODE_NOCONVERSION        as long    = &h100    ' 
Global const IME_CMODE_EUDC                as long    = &h200    ' EUDC(ってなんだ?)
Global const IME_CMODE_SYMBOL            as long = &h400    ' シンボル記号(英数の?)
Global const IME_CMODE_FIXED            as long    = &h800    '

Global const MB_OK                        as long    = 0
Global const MB_ICONHAND                 as long    = 16
Global const MB_ICONQUESTION            as long    = 32
Global const MB_ICONEXCLAMATION         as long    = 48
Global const MB_ICONASTERISK            as long    = 64

Sub Main

'GlobalScope.BasicLibraries.LoadLibrary("XrayTool")
'xray ThisComponent
GlobalScope.BasicLibraries.LoadLibrary("ProjectBEE")
msgBeep(64)
immToggle

End Sub


' --------------------------------------
'    びーぷ(ExampleDeclare改)
Declare Sub MessageBeep Lib "user32.dll"( byVal long )
Sub msgBeep(optional mb as long)
    if isMissing(mb) then mb = MB_OK
    MessageBeep( mb )
end Sub

' --------------------------------------
'    IME制御
' --------------------------------------
function imm(optional sw as long, optional mode as long) as long

    dim hWND as long
    dim hIMC as long
    dim PID() as byte
    dim cmode as long
    dim smode as long
    
    hWND =  StarDesktop.CurrentFrame.ContainerWindow.getWindowHandle(PID, SYSTEM_WIN32)                    ' good
    hIMC = ImmGetContext(hWnd)
    
    if IsMissing(sw) then                                    ' sw がなければ状態問い合わせ
        if (GetGUIType() <> 1) then
            imm = -1                                        ' Windows 以外は 戻り値:=-1
        else
            if (ImmGetOpenStatus(hIMC) = 0) then             ' imm の状態取得
                imm = 0                                        ' OFF なら戻り値:=0
            else                                             ' ON なら...
                ImmGetConversionStatus(hIMC, cmode, smode)    ' 変換モード取得
                imm = cmode                                    ' 戻り値:=変換モード
            end if
        end if
    else                                                    ' sw 指定時は imm 制御
        imm = ImmSetOpenStatus(hIMC, sw)                    ' 戻り値:= ImmSetOpenStatus の処理結果(BOOLEAN)

        if (sw) then                                        ' imm を ON にすれば...
            if IsMissing(mode) then mode = IME_CMODE_JAPANESE _
              + IME_CMODE_FULLSHAPE _
               + IME_CMODE_ROMAN
            ImmGetConversionStatus(hIMC, cmode, smode)
            imm = ImmSetConversionStatus(hIMC, mode, smode)    ' 戻り値:= ImmSetConversionStatus の処理結果(BOOLEAN)
        end if
    end if

    ImmReleaseContext(hWND,hIMC)

'    if (imm) then msgBeep(MB_ICONEXCLAMATION)

end function

' --------------------------------------
'    IME TOGGLE
sub immToggle

    dim hWND as long
    dim hIMC as long
    dim PID() as byte
    dim stat as long
        
    hWND = StarDesktop.CurrentFrame.ContainerWindow.getWindowHandle(PID, SYSTEM_WIN32)
    hIMC = ImmGetContext(hWnd)
    
    stat = ImmGetOpenStatus(hIMC)
    stat = 1 - stat
    ImmSetOpenStatus(hIMC,stat)
    
    ImmReleaseContext(hWND,hIMC)

end sub

sub immOn    ' --------------------------
    imm(TRUE, IME_CMODE_JAPANESE+IME_CMODE_FULLSHAPE +IME_CMODE_ROMAN)
end sub

sub immOff    ' --------------------------
    imm(FALSE)
end sub

sub immHira    ' --------------------------
    imm(TRUE, IME_CMODE_JAPANESE+IME_CMODE_FULLSHAPE _
 +IME_CMODE_ROMAN)
end sub

sub immKata    ' --------------------------
    imm(TRUE, IME_CMODE_JAPANESE+IME_CMODE_KATAKANA+IME_CMODE_FULLSHAPE _
 +IME_CMODE_ROMAN)
end sub

sub immCode    ' --------------------------
    imm(TRUE, IME_CMODE_JAPANESE+IME_CMODE_FULLSHAPE+IME_CMODE_CHARCODE)
end sub

sub immKbd    ' --------------------------
    imm(TRUE, IME_CMODE_JAPANESE+IME_CMODE_FULLSHAPE+IME_CMODE_SOFTKBD)
end sub

eclipse の設定(Preferences)Web HTML 検証(Validate) の項を開く。
要素属性ドキュメント・タイプコメントCDATAセクション処理命令エンティティテキスト領域の各項目の設定を任意に変更する。
エラー」や「警告」のチェックをルーズにしないと「問題」が山積みになって大変。

12年ぶりの数独

おつむのリハビリに数独(Number place)を解くプログラムを書いてみました。
むか〜しVisualC/C++の練習で書いたことがあったけど、
いまとなってはリハビリにはちょうどいいかも。

で、今日の今日まで知らなかったのだけど、
C++ のスコープで
for (int i=0; i<9; i++) {
...
}
としたときに、変数 i は for 文が終わると消えちゃうように
変わったんですね。以前は for の含まれるブラケットの中では
存在してたのに。

int main()
{
  for (int i=0; i<9; i++)  {  // ここで宣言しとく 
  ...
  }
 
  for (int i=0; i<9; i++)  { // 以前は int があるとエラー 
  ...
  }

  for (i=0; i<9; i++)  { // 最近は int がないとエラー 
  ...
  }
  return 0;
} 

知らんかった。
やっぱリハビリが必要だわ。

//======================================
// Name        : sudoku.cpp
// Author      : tensu
// Version     :
// Copyright   : (c) tensu 2009
// Description : SUDOKU in C++, Ansi-style
//======================================


#include <iostream>
using namespace std;

int num[9][9] = {
        {1,0,0, 2,0,0, 3,0,0},
        {0,0,0, 0,3,0, 0,4,1},
        {0,0,3, 0,0,4, 0,0,5},

        {3,0,0, 1,0,2, 5,0,0},
        {0,4,0, 0,0,0, 0,6,0},
        {0,0,5, 8,0,9, 0,0,7},

        {5,0,0, 6,0,0, 7,0,0},
        {9,6,0, 0,7,0, 0,0,0},
        {0,0,7, 0,0,8, 0,0,9},
};

int ans=0;

void dump()
{
    cout << "Ans: " << ++ans << endl;
    cout << " x";
    for (int x=0; x<9; x++) cout << " " << x+1;
    cout << endl;
    cout << " *";
    for (int x=0; x<9; x++) cout << "--";
    cout << endl;
    for (int y=0; y<9; y++) {
        cout << "y" << y+1 << "|";
        for (int x=0; x<9; x++)
            cout << num[y][x] << " ";
        cout << endl;
    }
}

void probe(int loc)
{
    ++ent;
    if (loc==81) {
        dump();
    } else {
        int x = loc % 9;
        int y = loc / 9;
        int bx = (x/3)*3;
        int by = (y/3)*3;

        if (num[y][x]!=0) {
            probe(loc+1);
        } else {
            for (int n=1; n<=9; n++) {
                bool used = false;
                int ix,iy;
                for (ix=0; !used && ix<9; ix++)
                    if (num[y][ix]==n) used=true;
                for (iy=0; !used && iy<9; iy++)
                    if (num[iy][x]==n) used=true;
                for (iy=by; !used && iy<by+3; iy++)
                    for (ix=bx; !used && ix<bx+3; ix++)
                        if (num[iy][ix]==n) used=true;
                if (used) continue;

                num[y][x]=n;
                probe(loc+1);
                num[y][x]=0;
            }
        }
    }
}

int main() {
    cout << "9x9" << endl;

    probe(0);
    if (!ans)
        cout << "No Ans." << endl;

    return 0;
}

---
結果:
9x9
Ans: 1
 x 1 2 3 4 5 6 7 8 9
 *------------------
y1|1 9 4 2 8 5 3 7 6 
y2|7 5 2 9 3 6 8 4 1 
y3|6 8 3 7 1 4 9 2 5 
y4|3 7 6 1 4 2 5 9 8 
y5|8 4 9 3 5 7 1 6 2 
y6|2 1 5 8 6 9 4 3 7 
y7|5 2 1 6 9 3 7 8 4 
y8|9 6 8 4 7 1 2 5 3 
y9|4 3 7 5 2 8 6 1 9 
Ans: 2
 x 1 2 3 4 5 6 7 8 9
 *------------------
y1|1 9 4 2 8 5 3 7 6 
y2|7 5 8 9 3 6 2 4 1 
y3|6 2 3 7 1 4 9 8 5 
y4|3 7 6 1 4 2 5 9 8 
y5|8 4 9 3 5 7 1 6 2 
y6|2 1 5 8 6 9 4 3 7 
y7|5 8 1 6 9 3 7 2 4 
y8|9 6 2 4 7 1 8 5 3 
y9|4 3 7 5 2 8 6 1 9 

出力される実行ファイルの名前の変更方法。

Project Explorer で 拡張子 .pro のファイルを開き、
TARGET = target name
のところを希望の名前に変える。
拡張子 .exe は不要。

Makefile や Makefile.Release を変えてもだめ。

Windows で作った Qt4 のコードを Linux でコンパイルしてみたくなったので環境整備。
Eclipse + Qt4 で Win と Linux のお手軽クロスができるはず。

Qtのダウンロードページ http://www.qtsoftware.com/downloads-jp から
バイナリ http://www.qtsoftware.com/downloads/sdk-linux-x11-32bit-cpp を落として
Webページに書いてある説明


On Linux/Unix, you need to make the file executable in order to run it. You can either do this with your desktop's file manager or, at the command line, type:

chmod u+x qt-sdk-linux-x86-opensource-2009.02.bin
( ダウンロードしたファイルに実行属性をつけろということらしい。 )


You should now be able to execute the file as normal. You can do this from the command line by typing:

./qt-sdk-linux-x86-opensource-2009.02.bin
( あとはただじっこうするだけらしい。 )

にしたがって実行するも「ちゃんとダウンロードできてないんじゃないの」とかいわれて実行できない。

しかたないのでソースの Qt for Open Source C++ development on Linux/X11 をダウンロードする。
http://www.qtsoftware.com/downloads/linux-x11-cpp

で再び説明に従い、
tar xvf qt-x11-opensource-src-4.5.1.tar.gz
して、
cd qt-x11-opensource-src-4.5.1
して、
./configure
したらエラーがでる。

QMAKE_INCDIR_X11 と QMAKE_LIBDIR_X11 の設定を調べろというが、
調べるとうちの ubuntu には /usr/X11R6/include とか /usr/X11R6/lib がない。
そういうもんなんだろうか?

あきらめるのもイヤなのであれこれ数時間いじる。
結局 synaptic で qt4 -desiner やら qt4-demos やらをインストールすると
無事に configure できた。

その後 make にかかる。

3時間後、
...まだ make が終わらない。

UTM 再び

Qt4の練習がてら緯度経度をUTMに変換するツールを久々に作ってみた。

http://cid-e844b718ee02a287.skydrive.live.com/browse.aspx/.Public/utm

僕の作る程度のプログラムなら Eclipse CDT と Qt4 SDK があれば Visual C/C++ の必要性はかなり低くなる。
Visual C/C++ が .NET に移行してからなんか使う気があまりしないでいたけど、今後ますます使わなくなるかもしれない。

この練習プログラムのソースが Ubuntu の上でそのまま通って実行ファイルができるなら素敵だ。

デザイン変更

ブログのデザインをいじったりダイナミックパブリッシングにしてみたりしたら server Error とかになってしまった。
調べるのも面倒なのでシステムを MT3 から MT4 に更新してみた。
でもやっぱり server Error は直らず。
仕方ないので調べたら、.htaccess がまずいらしい。
Option〜 の行をコメントアウトするとよいというのでやってみた。
記事はダイナミック表示できるけどトップページはうまくいかない。
しょうがないのでトップはスタティックなままで妥協。

MT4はMT3よりずいぶん操作性が改善されているのね。
もっと早く入れ替えておけばよかった。

なお変更に伴い一部アクセスできないリンクができてます。
気がついたものから直します。

eclipse + qt4.5

Vista SP2 にインストール。

用意したもの、以下のとおり。はっきりいってよくわかっていない。
eclipse-cpp-ganymede-SR2-win32.zip ... (1)
qt-sdk-win-opensource-2009.02.1.exe ...(2)
qt-eclipse-integration-win32-1.5.1.exe ... (3)

次も一応ダウンロードだけしといた。
qt-win-opensource-4.5.1-mingw.exe ... (4)
qt-creator-win-opensource-1.1.1.exe ... (5)

(1) を展開。 c:\opt\eclipse\ に置く。
このディレクトリにはほかのバージョンの eclipse も置かれているので
実行ファイル(exlipse.exe)の位置は"C:\opt\eclipse\eclipse\eclipse.exe"

(2) を実行。 c:\opt\Qt\2009.02 にインストール。
C:\Program files\ 以下にインストールするのがいいんだろうけどなんとなく変えてみた。

(3) を実行。 C:\opt\Trolltech\Eclipse にインストール。
Eclipse のインストレーションは C:\opt\eclipse\eclipse
MinGW のインストレーションは C:\opt\Qt\2009.02\mingw\bin
をそれぞれ指定。

(4),(5) は今日は使わなかった。

Eclipse を起動。
パスを追加する。メニュー(Window) (Preference) [QT]
Bin Path: C:\opt\Qt\2009.02\qt\bin
Include Path: C:\opt\Qt\2009.02\qt\include

で、コンパイルはできるけどデバッグと実行ができない。
なにが足らないんだろ。。。

--- 1時間後、
パス(C:\opt\Qt\2009.02\qt\bin)を通したらエクスプローラから直接実行はできた。
でもまだデバッグできない。

--- さらに1時間後、
http://lists.trolltech.com/qt-interest/2008-06/msg00543.html
を見つけてプロパティをいじる。
[ Debugger Tab - Main Tab ]のデバッガのパス変更と、
C:\opt\Qt\2009.02\mingw\bin\gdb.exe
[ Debugger Tab - Shared Libraries Tab ]のライブラリの追加。
C:\opt\Qt\2009.02\lib
で何とか動いたみたい。

DOS窓表示のレジストリ

ずいぶん以前からウィンドウズをインストールするたびに追加するレジストリ。
Vista でも有効だった。

 HKEY_CLASSES_ROOT$Folder$shell$shell.reg 
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Folder\shell\shell] @="コマンドシェル(&S)" [HKEY_CLASSES_ROOT\Folder\shell\shell\command] @="cmd.exe /k cd \"%L\""

Vista に apache2をインストールした後php5をインストールする。
このとき欲張って Extentions をすべて指定したりしないこと。

データベース関係をはじめとした DLL が足りないので起動できなくなる。
自分が使う拡張だけに絞ること。

PEARも指定するとうまくいかない。

--- このようなメッセージがいっぱい出てくる ---
PHP Warning: PHP Startup: Unable to load dynamic library 'C:\\opt\\PHP\\ext\\php_exif.dll' - PHP Warning: PHP Startup: Unable to load dynamic library 'C:\\opt\\PHP\\ext\\php_fdf.dll' - PHP Warning: PHP Startup: Unable to load dynamic library 'C:\\opt\\PHP\\ext\\php_interbase.dll' -
PHP Warning: PHP Startup: Unable to load dynamic library 'C:\\opt\\PHP\\ext\\php_mcrypt.dll' - PHP Warning: PHP Startup: Unable to load dynamic library 'C:\\opt\\PHP\\ext\\php_mhash.dll' -
...
Cannot find module (IP-MIB): At line 0 in (none)
Cannot find module (IF-MIB): At line 0 in (none)
Cannot find module (TCP-MIB): At line 0 in (none)
...
PHP Notice: Constant XML_ELEMENT_NODE already defined in Unknown on line 0
PHP Notice: Constant XML_ATTRIBUTE_NODE already defined in Unknown on line 0
PHP Notice: Constant XML_TEXT_NODE already defined in Unknown on line 0
...

インストール時に指定しなかった拡張は php.ini の最後のほうでコメントアウトされているので
必要になったときにコメントをはずせばいい。

apache は Skype に注意

Vista にいろいろとアプリをインストールしていて嵌ったポイント

skype をインストールした後に apache 2.2 をインストールしようとすると失敗する。
なんと skype が 80番ポートを握ってしまうのが原因。
普通のユーザーならHTTPサーバーなど起てないし80なら企業やホテルの防火壁でも
開いていることが多いだろうから便利なのだろうけど。ちょっと酷いんじゃない。

参考ページ: http://g2s.livedoor.biz/archives/51175437.html?1244254368

OpenOffice BASIC で strcpy

Windows の IMM の API で ImmGetConversionList を使って
漢字の読みを取り出したかったんだけどうまくいかない。
VBだとできるらしいんだけど。

いろいろと試行錯誤していると本題とは関係ないけど面白いことに気が付いた。
C の基本関数が OOo の BASIC からも使える

----------------------------------------
REM  *****  BASIC  *****

declare function strncpy lib "ntdll" (byRef dst as string, _
	byRef src as string, byVal siz as long)
declare function strlen lib "ntdll" (byRef dst as string) as long

Sub Main
	dim src as string : 	src = "文字列コピー"
	dim dst as string : 	dst =  string$(8,0)
	siz = len(dst)
	dummy = strncpy(dst, src, siz)
	msgbox "'"& src &"' ("& strlen(src) &"byte) -> '" _
		& dst &"' (" & strlen(dst) &"bytes)"
End Sub
----------------------------------------
つうことは、なにか。
C で DLL 書いてやれば BASIC の関数の拡張は簡単って事か?
# きっともっと別の、そして正規の方法があるんだけど。
VB のコードを参考にして OpenOffice.org のBASICで API からの文字列を
受け取ってみた。

参照先: 「DLL 関数から文字列を返す」
http://msdn.microsoft.com/ja-jp/library/cc376816.aspx

VB と異なるところは、Declare Function で文字列を受け取るバッファを
 byRef でなく byVal で宣言しなければ期待した動作が行われないこと。
バッファから String 変数にコピーする際は Null文字(¥0) でターミネート
しているらしいこと。

REM ***** BASIC ***** Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" _ (ByVal nBufferLength As Long, ByRef lpBuffer As String) As Long Sub Main msgbox GetTempDir End Sub function GetTempDir() As String ' 使用している Temp フォルダへのパスを返します。 ' Windows を起動するには一時フォルダが必要なため、確実に ' パスには 1 が返されますが、一応 GetTempPath の戻り値を ' 確認します。 Dim strTempPath As String Dim lngTempPath As Long ' 文字列に Null 文字を入力します。 strTempPath = String$(255, 0) ' 0 = vbNullChar ' 文字列の長さを取得します。 lngTempPath = Len(strTempPath) ' GetTempPath を呼び出し、文字列の長さと文字列を渡します。 L = GetTempPath(lngTempPath, strTempPath) If (L > 0) Then ' GetTempPath はパスを文字列に返します。 ' 最初の Null 文字を切り捨てます。 GetTempDir = strTempPath Else GetTempDir = "" End If End function

C:¥>fsutil
---- サポートされるコマンド ----

behavior ファイル システムの挙動の制御
dirty ボリュームの dirty ビットの管理
file ファイルに固有のコマンド
fsinfo ファイル システム情報
hardlink ハードリンクの管理
objectid オブジェクト ID の管理
quota クォータの管理
reparsepoint 再解析ポイントの管理
sparse スパース ファイルの制御
usn USN の管理
volume ボリュームの管理

C:¥>fsutil behavior
---- サポートされる BEHAVIOR コマンド ----

query ファイル システムの挙動パラメータの照会
set ファイル システムの挙動パラメータの変更

C:¥>fsutil behavior query
使用法 : fsutil behavior query <オプション>

<オプション>

disable8dot3
allowextchar
disablelastaccess
quotanotify
mftzone

C:¥>fsutil behavior set
使用法 : fsutil behavior set <オプション> <値>

<オプション> <値>

disable8dot3 1 | 0
allowextchar 1 | 0
disablelastaccess 1 | 0
quotanotify 1 秒から 4294967295 秒
mftzone 1 から 4

C:¥>fsutil dirty
---- サポートされる DIRTY コマンド ----

query dirty ビットの照会
set dirty ビットの設定

C:¥>fsutil dirty query
使用法 : fsutil dirty query <ボリュームパス名>
例 : fsutil dirty query C:

C:¥>fsutil dirty set
使用法 : fsutil dirty set <ボリュームパス名>
例 : fsutil dirty set C:

C:¥>fsutil file
---- サポートされる FILE コマンド ----

findbysid セキュリティ識別子でファイルを検索
queryallocranges ファイルに割り当てられた範囲の照会
setshortname ファイルの短い名前の設定
setvaliddata ファイルの有効なデータ長の設定
setzerodata ファイルのゼロ データの設定
createnew 指定されたサイズの新しいファイルを作成

C:¥>fsutil file findbysid
使用法 : fsutil file findbysid <ユーザー> <ディレクトリ>
例 : fsutil file findbysid scottb C:¥users

C:¥>fsutil file queryallocranges
使用法 : fsutil file queryallocranges offset=<val> length=<val> <ファイル名>
offset : ファイルのオフセット、照会する範囲の開始点
length : 範囲のサイズ (バイト)
例 : fsutil file queryallocranges offset=1024 length=64 C:¥Temp¥sample.txt

C:¥>fsutil file setshortname
使用法 : fsutil file setshortname <ファイル名> <shortname>
例 : fsutil file setshortname C:¥testfile.txt testfile

C:¥>fsutil file setvaliddata
使用法 : fsutil file setvaliddata <ファイル名> <datalength>
例 : fsutil file setvaliddata C:¥testfile.txt 4096

C:¥>fsutil file setzerodata
使用法 : fsutil file setzerodata offset=<val> length=<val> <ファイル名>
offset : ファイルのオフセット、ゼロに設定する範囲の開始点
length : ゼロの範囲の長さ (バイト)
例 : fsutil file setzerodata offset=100 length=150 C:¥Temp¥sample.txt

C:¥>fsutil file createnew
使用法 : fsutil file createnew <ファイル名> <長さ>
例 : fsutil file createnew C:¥testfile.txt 1000

C:¥>fsutil fsinfo
---- サポートされる FSINFO コマンド ----

drives ドライブをすべて一覧表示
drivetype ドライブの種類の照会
volumeinfo ボリューム情報の照会
ntfsinfo NTFS 固有のボリューム情報の照会
statistics ファイル システム統計情報の照会

C:¥>fsutil fsinfo drives

ドライブ: A:¥ C:¥ D:¥ E:¥

C:¥>fsutil fsinfo drivetype
使用法 : fsutil fsinfo drivetype <ボリュームパス名>
例 : fsutil fsinfo drivetype C:

C:¥>fsutil fsinfo volumeinfo
使用法 : fsutil fsinfo volumeinfo <ボリュームパス名>
例 : fsutil fsinfo volumeinfo C:¥

C:¥>fsutil fsinfo ntfsinfo
使用法 : fsutil fsinfo ntfsinfo <ボリュームパス名>
例 : fsutil fsinfo ntfsinfo C:

C:¥>fsutil fsinfo statistics
使用法 : fsutil fsinfo statistics <ボリュームパス名>
例 : fsutil fsinfo statistics C:

C:¥>fsutil hardlink
---- サポートされる HARDLINK コマンド ----

create ハードリンクの作成

C:¥>fsutil hardlink create
使用法 : fsutil hardlink create <新しいファイル名> <既存のファイル名>
例 : fsutil hardlink create c:¥foo.txt c:¥bar.txt

C:¥>fsutil objectid
---- サポートされる OBJECTID コマンド ----

query オブジェクト ID の照会
set オブジェクト ID の変更
delete オブジェクト ID の削除
create オブジェクト ID の作成

C:¥>fsutil objectid query
使用法 : fsutil objectid query <ファイル名>
例 : fsutil objectid query C:¥Temp¥sample.txt

C:¥>fsutil objectid set
使用法 : fsutil objectid set <ObjectId> <BirthVolumeId> <BirthObjectId> <DomainId> <ファイル名>
ObjectId : 32 桁の 16 進データ
BirthVolumeId : 32 桁の 16 進データ
BirthObjectId : 32 桁の 16 進データ
DomainId : 32 桁の 16 進データ
値はすべて次の形式の 16 進数でなければなりません 40dff02fc9b4d4118f120090273fa9fc
例 : fsutil objectid set 40dff02fc9b4d4118f120090273fa9fc
f86ad6865fe8d21183910008c709d19e
40dff02fc9b4d4118f120090273fa9fc
00000000000000000000000000000000 C:¥Temp¥sample.txt

C:¥>fsutil objectid delete
使用法 : fsutil objectid delete <ファイル名>
例 : fsutil objectid delete C:¥Temp¥sample.txt

C:¥>fsutil objectid create
使用法 : fsutil objectid create <ファイル名>
例 : fsutil objectid create C:¥Temp¥sample.txt

C:¥>fsutil quota
---- サポートされる QUOTA コマンド ----

disable クォータの追跡と強制の無効化
track クォータの追跡の有効化
enforce クォータの強制の有効化
violations クォータ違反の表示
modify ユーザーのディスク クォータの設定
query ディスク クォータの照会

C:¥>fsutil quota disable
使用法 : fsutil quota disable <ボリュームパス名>
例 : fsutil quota disable C:

C:¥>fsutil quota track
使用法 : fsutil quota track <ボリュームパス名>
例 : fsutil quota track C:

C:¥>fsutil quota enforce
使用法 : fsutil quota enforce <ボリュームパス名>
例 : fsutil quota enforce C:

C:¥>fsutil quota violations
System イベント ログを検索中...
Application イベント ログを検索中...
クォータ違反は検出されませんでした

C:¥>fsutil quota modify
使用法 : fsutil quota modify <ボリュームパス名> <しきい値> <制限> <ユーザー>
例 : fsutil quota modify c: 3000 5000 domain¥user

C:¥>fsutil quota query
使用法 : fsutil quota query <ボリュームパス名>
例 : fsutil quota query C:

C:¥>fsutil reparsepoint
---- サポートされる REPARSEPOINT コマンド ----

query 再解析ポイントの照会
delete 再解析ポイントの削除

C:¥>fsutil reparsepoint query
使用法 : fsutil reparsepoint query <ファイル名>
例 : fsutil reparsepoint query C:¥Server

C:¥>fsutil reparsepoint delete
使用法 : fsutil reparsepoint delete <ファイル名>
例 : fsutil reparsepoint delete C:¥Server

C:¥>fsutil sparse
---- サポートされる SPARSE コマンド ----

setflag スパースに設定
queryflag スパースの照会
queryrange 範囲の照会
setrange スパース範囲の設定

C:¥>fsutil sparse setflag
使用法 : fsutil sparse setflag <ファイル名>
例 : fsutil sparse setflag C:¥Temp¥sample.txt

C:¥>fsutil sparse queryflag
使用法 : fsutil sparse queryflag <ファイル名>
例 : fsutil sparse queryflag C:¥Temp¥sample.txt

C:¥>fsutil sparse queryrange
使用法 : fsutil sparse queryrange <ファイル名>
例 : fsutil sparse queryrange C:¥Temp¥sample.txt

C:¥>fsutil sparse setrange
使用法 : fsutil sparse setrange <ファイル名> <開始オフセット> <長さ>
例 : fsutil sparse setrange C:¥Temp¥sample.txt 65536 131072

C:¥>fsutil usn
---- サポートされる USN コマンド ----

createjournal USN ジャーナルの作成
deletejournal USN ジャーナルの削除
enumdata USN データの列挙
queryjournal ボリュームの USN データの照会
readdata ファイルの USN データの読み取り

C:¥>fsutil usn createjournal
使用法 : fsutil usn createjournal m=<max-value> a=<alloc-delta> <ボリュームパス名>
例 : fsutil usn createjournal m=1000 a=100 C:

C:¥>fsutil usn deletejournal
使用法 : fsutil usn deletejournal <フラグ> <ボリュームパス名>
<フラグ>
/D : Delete
/N : Notify
Eg : usn deletejournal /D C:

C:¥>fsutil usn enumdata
使用法 : fsutil usn enumdata <file ref#> <lowUsn> <highUsn> <ボリュームパス名>
例 : fsutil usn enumdata 1 0 1 C:¥

C:¥>fsutil usn queryjournal
使用法 : fsutil usn queryjournal <ボリュームパス名>
例 : fsutil usn queryjournal C:

C:¥>fsutil usn readdata
使用法 : fsutil usn readdata <ファイル名>
例 : fsutil usn readdata C:¥Temp¥sample.txt

C:¥>fsutil volume
---- サポートされる VOLUME コマンド ----

dismount ボリュームのマウント解除
diskfree ボリュームの空き領域の照会

C:¥>fsutil volume dismount
使用法 : fsutil volume dismount <ボリュームパス名>
例 : fsutil volume dismount C:

C:¥>fsutil volume diskfree
使用法 : fsutil volume diskfree <ボリュームパス名>
例 : fsutil volume diskfree C:

連絡先

nakanohito