「夫を成功」へ導く妻の秘訣 座談会

こんにちは。初歩的な質問かもしれませんが、お分かりの方は是非ご教授願います。以前にもロケールとストリングテーブルについてのQAがNo.445463でされていますが、こちらで出された回答と現象が違うかもしれませんので、書いてみました。
<現象>
開発環境上(VisualBasic6.0Enterprise)でストリングテーブルを日本語と英語(U.S.)の2つ設定し、同環境上でロケールを日本語⇔英語切替を行いながらデバッグ実行をしました。その際はロケールに対応したストリングが呼び出され、該当した言語で表現されました。
しかし、実際作成したexeにて同様の実行を行ったところ、必ず日本語のストリングが呼び出されてしまい。英語ロケール時に英語テーブルが呼ばれません。
<OS環境>
コンパイル・実行ともにWindows2000professional(日本語版・ロケールも日本語)です。

No.445463の方の例を忠実に手直ししようと思いましたが、多言語テーブルの場合とちょっと違う気がします。この現象を解決するにはどうすればよろしいのでしょうか?あと、自分の解釈ではロケールとは"地域のオプション"の"全般"タブにあるコンボのことだと思うのですが、他にも設定が必要なんでしょうか?
ご回答、よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

文字化けについて、、、



日本OSでリソースから読み取った日本語文字が化けるというのですか?
もしそうなら、、、
リソースから読まずに、固定で画面に文字列をセットしても化けるのですか?
画面でなくて、メッセージボックスで表示しても化けますか?

固定で決めうちした文字列で化けて、メッセージボックスでは化けない場合は、
フォームロード時に、最初にフォームのフォント、次にフォームのコントロール類のフォントを変更してあげたら対応できると思います。
おすすめはMSUゴシック

そうでなければ、化ける場合をパターン別に細かく書いてもらわないと答えようがありません。。。
    • good
    • 0
この回答へのお礼

TAGOSAKU7さん、お忙しいところの即レスにもかかわらずお返事遅くなり申し訳ありません。
文字化けに関してですが、前回教えていただいたロジックを実行したときに起こったことなのですが、「日本語」または「ENGLISH」をストリングテーブルから参照しダイアログで表示するとき、開発環境にてシステムロケール=英語(U.S.)だと「ENGLISH」と表示していたところ、exe実行時に「????」などのように表示されてしまうのです。フォントはダイアログmsgbox関数が持つデフォルトのものであると思われます。英語ストリングが選択されていれば「ENGLISH」と正しく表示されることが然りではないでしょうか?ちなみに他の一部のアプリケーションで同様に「?????」と表示されている個所がありました。ちなみにそのときスタートメニューは日本語で表示されてました(当たり前かも)
また、実はあれからいろいろ調べていくうちに、実行時に得るロケールはexeを実行するOS自身の言語版に深く依存していることが分かりました。具体的なロジックレベルまで理解している訳ではありませんが、各国語版のOSはそれぞれネイティブの言語(UI Languageというらしいです)を内部的に持ち、その言語に基づいてストリングテーブルの選択を行うということのようです。ロジックでこれを書き換えることは不可能(または相当手間がかかる)らしいです。対応としてはMSDN上ではサテライトDLLを各言語毎に作成し、実行環境毎に個別に呼ぶ方法、他にIPDKというツールがあるようですが、現状ではまったく理解できてないのでここで詳しく述べることができません。こういったツールについてご存知でしたらヤブヘビということもありますね・・・

お礼日時:2003/02/06 00:53

調べは限界なので、想像の世界を書き込みます。



SetThreadLocaleは、現在のスレッドに対して、ロケールを設定するようです。OS全体に影響するものではありません。

んで、デバッグ環境とEXEにしてからの実行結果が違う事について、、、
「親」と言う事に注目してみると・・・
※デバッグ環境
   (1)デスクトップ → (2)VB → (3)デバッグ環境で擬似EXE
※EXE
   (1)デスクトップ → (2)EXE
となります。
スレッドと言う概念を元に考えると、デスクトップは親として扱われないので、最上位の親が、デバッグ環境とEXEでは違うことになります。

VB自身が開発ツールであることと、デバッグ環境とEXE環境の実行結果から、私たちの見えないところで、VB自身が[GetUserDefaultLCID][SetThreadLocale]をコールしている事が想像できます。
だからこそEXEにしたら、それらは自身でコールしてあげないといけないのだと思います。
(想像だらけでスマソ)


さらに、、、文字化けですが、、、、
読み込んだ文字をそのままフォームに張って、「文字化けがおきる」と言ってませんか?
ストリングテーブルが英語なら、MSGBOXで表示したらうまくいかないですか?
そこでうまく表示できたなら、ロケール以前にフォントの問題だと思われます。

それと、その現象が起こるということは、ストリングテーブルのロケール反映ができたとして捕らえておきますね。
    • good
    • 0
この回答へのお礼

TAGOSAKU7さん、引続きお付き合い頂き、ありがとうございます。想定とはいえ、処理系作成者(MS)くらいしか核心が分からないことかもしれませんね。実際APIを組み込んでテストしてませんが、現状の知識ではAPIを組み合わせることが最善のようです。しかし、この点についてはMSDNの説明が不十分である可能性もありますので、結論付けは少し時間を頂きたいと思います。後半仰られた文字化けの件ですが、会社PCで再現させたところ(かなり危険かも)原因は日本語の文字コードを変換できなかったために"???"という表示になるようです→前回は言葉が足りませんでした。やはりストリングテーブルのロケール反映は不能でした・・・と、いうことは、手動でのロケール設定は不可能ということかなぁ。それとも英語版OSを用意してテストすべきでしょうかねぇ・・・

お礼日時:2003/01/31 13:34

質問者が履歴で挙げた過去スレに答えていた者です。



前回の質問は、
開発環境:US版OS
実行環境:多国(日本語は含まない)
という状況でした。
悲しい事にそんな環境が手元にあるわけもなく、
「日本語版での環境で、日本語テーブルを含まない、複数のストリングテーブル」
を対象にした方法を述べたつもりです。


今回の場合は、前回の質問とちょっと違います。
「日本語版での環境で、日本語テーブルを含む、複数のストリングテーブル」
です。
そうであれば、特にリソースをスクリプト化する必要もありません。
手元にサンプルがあったのでサンプルを載せておきます。


※注意事項----------非常に大事-----------
デバッグ環境だと、対応しないので、EXEの状態で試してみてください。
※注意事項----------非常に大事-----------

ちなみに
日本語ロケールID:1041
英語USロケールID:1033
です


Project1.vbp(プロジェクト)
├Module1.bas(モジュール)
└Test.res(リソース)

*****Module1.basの内容*****
Option Explicit

Public Declare Function GetUserDefaultLCID Lib "KERNEL32" () As Long
Public Declare Function SetThreadLocale Lib "KERNEL32" (ByVal Locale As Long) As Long
Public Const API_FALSE = &H0&

Sub Main()
  Dim lngNowLCID As Long   '//現在のロケールID
  Dim lngNewLCID As Long   '//入力後のロケールID
  Dim strRet   As String  '//インプットボックス戻り
  
  '地域のオプションでセットされているロケールを取得する
  lngNowLCID = GetUserDefaultLCID
  
  Do
    strRet = InputBox("現在のロケールは[" & lngNowLCID & "]です", _
          "ロケールIDを指定してください。", lngNowLCID)
    
    '数値のみ対応
    If Not IsNumeric(strRet) Then
      Exit Sub
    End If
    lngNewLCID = CLng(strRet)
    
    '取得したロケールを、現在のスレッドにセット
    If API_FALSE = SetThreadLocale(lngNewLCID) Then
      'ロケール設定エラー
      MsgBox "ロケール設定に失敗", vbCritical Or vbOKOnly
    Else
      'リソースを読んで表示
      MsgBox LoadResString(101), vbInformation Or vbOKOnly
    End If
  Loop
  
End Sub

*****Test.resの内容*****
構成:日本語テーブル/英語(U.S.)テーブルの計2つのテーブル
ID:101
内容:日本語テーブル側の文字列="日本語"/英語(U.S.)テーブル側の文字列="English"




それと、、、
>同環境上でロケールを日本語⇔英語切替を行いながらデバッグ実行をしました。
>その際はロケールに対応したストリングが呼び出され、該当した言語で表現されました。
とありますが、おそらくVBは
デバッグでは、GetUserDefaultLCID 関数(コンパネで設定されたロケールID)
EXEでは、GetSystemDefaultLCID 関数(OSが持っているロケールID)
を使用しているからだと、勝手に思っています。(違っていたらゴメソ)
    • good
    • 0
この回答へのお礼

TAGOSAKU7さん、こんにちは。早速教えていただいたソースを試してみました(自宅でですが、同じ環境なのです)。GetUserDefaultLCIDでは正しく地域のオプションで設定したロケールIDを返しますが、実際ストリングテーブルを切り分けるトリガは別のようですね。ひょっとしてTAGOSAKU7さんはGetUserDefaultLCIDで取得したロケールIDをSetThreadLocaleでシステムに対して再度設定する、ということなんでしょうか?両方の関数の機能を考えると何とかなりそうですね?MSDNには「システムのLCIDを基準にして(GetSystemDefaultLCIDのことでしょうか?)、実行時に自動的に選択されます」とありますが、システムロケールを手動変更すると文字化けしてストリングテーブル以前の問題になっちゃうんですよねぇ・・・ともあれ、長文でのご回答、大変感謝いたします。もし追加情報ありましたら、是非お伝えください。

お礼日時:2003/01/30 22:21

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qリソースファイルとロケールについて

いつもお世話になっております。

OSのロケールに依存する文字列をロードするには、
複数ストリングテーブルを設定することになると思います。

しかし、英語版(Win2000/VB6.0)でコンパイルされた実行形式を、
コンパイル時とは異なるロケールに設定し、
(コントロールパネルの"地域のオプション":
英語版:Your Locale / 日本語版:現在のユーザー設定)
実行させた場合、現在設定されているロケールに対応するテーブルからロードされていません。

<ストリングテーブル>
・ 英語(U.S) <- 新規作成時にデフォルトで作成されているテーブル
・ ドイツ語(ドイツ) <- 追加

<コンパイル時環境>
Win2000英語版
・ 現在のユーザー設定 英語(U.S)
・ システムの言語設定 西ヨーロッパと米国(既定値)

<実行時環境>
・ 現在のユーザー設定 ドイツ語(ドイツ)
・ システムの言語設定 西ヨーロッパと米国(既定値)

<結果>
現在のユーザー設定にはかかわらず、常に英語(U.S)のテーブルからロードされる。


それならば、と思い、
その実行形式を日本語版OS(Win2000)で同様に動作させた場合には、
現在のユーザー設定と同一のストリングテーブルからロードされます。

なぜでしょうか。英語版の環境でどの設定が足りないのでしょうか。
それともAPIで何か特別な設定等を行わなければならないのでしょうか。

どうぞ宜しくお願いいたします。

いつもお世話になっております。

OSのロケールに依存する文字列をロードするには、
複数ストリングテーブルを設定することになると思います。

しかし、英語版(Win2000/VB6.0)でコンパイルされた実行形式を、
コンパイル時とは異なるロケールに設定し、
(コントロールパネルの"地域のオプション":
英語版:Your Locale / 日本語版:現在のユーザー設定)
実行させた場合、現在設定されているロケールに対応するテーブルからロードされていません。

<ストリングテーブル>
・ 英語(U.S) ...続きを読む

Aベストアンサー

リンク間違い

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=458254

QString Table リソースを条件によって切り換えたい(VS2005)

Visual Studio2005 VC++ のリソースビューに含まれる、String Table の内容を条件によって切り換えたいと考えています。
(より具体的には IDR_MAINFRAMEの文字列だけ変更できればよいのですが。)

String Table以外のリソースであれば、プリプロセッサの定義によって内容を変更できますが、String Tableだけは例外的に切り替えられないようです。

何かよい方法をご存知の方はご教授いただけますと幸いです。

Aベストアンサー

>リソースファイルを直接編集しても、その後で再びVC++で保存しなお
>すと、編集した箇所が元に戻されてしまうので、前者の対応では目的
>を実現できません。

IDR_MAINFAMEやAFX_IDS_APP_TITLEなどの
定義を.rc2ファイルに記述してはどうでしょうか。

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

Qダイアログ内コントロールの位置取得について

いつもお世話になっております。

ダイアログ内に配置されているコントロールの位置の取得方法について
ご教授頂きたく質問させていただきました。

私が試したところGetWindowRect( コントロールハンドル, &rc );
とするとありえないぐらい大きな座標が帰ってきます。

上記の方法ではうまくいきません。
ご教授よろしくお願いいたします。

Aベストアンサー

>http://msdn.microsoft.com/ja-jp/library/cc364604.aspx
より
>クライアント座標はクライアント領域の左上端からの相対座標なので、左上端の座標は常に (0,0) となります。
となっているため
>GetClientRectでダイアログ内の相対位置を取れます。
は間違っていました。

>もしかしたら便利な関数が存在するのでしょうか?
ないのかなぁと。
かわりにこんな関数を作っておくとか。

BOOL GetDlgItemRect(HWND hDlg, int nIDDlgItem, RECT* rct)
{
  BOOL bRet = FALSE;
  HWND hWnd = GetDlgItem(hDlg, nIDDlgItem);
  if (hWnd != NULL)
  {
    bRet = GetWindowRect(hWnd, rct);
    {
      bRet = ScreenToClient(hDlg, rct);
    }
  }
  return bRet;
}

>http://msdn.microsoft.com/ja-jp/library/cc364604.aspx
より
>クライアント座標はクライアント領域の左上端からの相対座標なので、左上端の座標は常に (0,0) となります。
となっているため
>GetClientRectでダイアログ内の相対位置を取れます。
は間違っていました。

>もしかしたら便利な関数が存在するのでしょうか?
ないのかなぁと。
かわりにこんな関数を作っておくとか。

BOOL GetDlgItemRect(HWND hDlg, int nIDDlgItem, RECT* rct)
{
  BOOL bRet = FALSE;
  HWND hWnd = GetDlgIt...続きを読む

Qボタンの表示の色、フォントを変更したい

VC++でプログラミングしています。
MFCのダイアログベースのEXEを造っています。
ダイアログにはボタンとエディットボックスを貼り付けています。
私がやりたいのは以下のことです。

・ボタンの色を設定したい
・ボタン、エディットボックスに表示する文字の色を設定したい
・ボタン、エディットボックスに表示する文字のフォント(サイズ)を設定したい

プロパティでサイズ変更すると全体に反映されてしまうので、個々の
コントロールについて制御したいと思っています。

ヘルプで調べて、それらしい関数を見つけるのですが使い方がわかりません。
VCを始めたばかりで、クラスの理解がまだ浅いです。。。
関数の説明は理解できても、「じゃあ、コードはどう書くの?」という状態です。
「○○ は ×× のメンバではありません」と、よく怒られてます。。。

識者の方、ご教授願います。
コードがどうなるのか知りたいので、簡単なサンプルコードがあると助かります。

また、質問ではないのですが、「この関数は○○をする」というのではなく、
「○○をするにはこの関数を使う」という様に調べられる、お勧めの書籍、
Webなどがありましたら教えてください。
今後の勉強に役立てたいと思っています。

VC++でプログラミングしています。
MFCのダイアログベースのEXEを造っています。
ダイアログにはボタンとエディットボックスを貼り付けています。
私がやりたいのは以下のことです。

・ボタンの色を設定したい
・ボタン、エディットボックスに表示する文字の色を設定したい
・ボタン、エディットボックスに表示する文字のフォント(サイズ)を設定したい

プロパティでサイズ変更すると全体に反映されてしまうので、個々の
コントロールについて制御したいと思っています。

ヘルプで調べ...続きを読む

Aベストアンサー

下2つについては以下でいけると思います。

class CMyDlg : CDialog
{
public:

  CFont m_cFont; //Dlgクラスのメンバとして用意
/*
  他のメンバ
*/
  virtual BOOL OnInitDialog(); //初期化

};


BOOL CMyDlg::OnInitDialog()
{
  //TODO:ここでFontを設定しておく(文字の色、サイズなど)

  //Fontを設定
  ((CButton *)GetDlgItem(IDC_BUTTON))->SetFont(&m_cFont,TRUE);

  //TODO:その他の初期化

  return TRUE;
}
//見易さのために、全角スペースを使っています;;

一番上はBitmapを貼り付けるか、CWndのメンバ関数を使って
塗りつぶすかどうかだと思います。

MFCではなく、C++Builderのページなのですが、少しいじればMFCでも使えるので、参考URLに示しておきます。

参考URL:http://market.agr.tottori-u.ac.jp/ken/tech.html

下2つについては以下でいけると思います。

class CMyDlg : CDialog
{
public:

  CFont m_cFont; //Dlgクラスのメンバとして用意
/*
  他のメンバ
*/
  virtual BOOL OnInitDialog(); //初期化

};


BOOL CMyDlg::OnInitDialog()
{
  //TODO:ここでFontを設定しておく(文字の色、サイズなど)

  //Fontを設定
  ((CButton *)GetDlgItem(IDC_BUTTON))->SetFont(&m_cFont,TRUE);

  //TODO:その他の初期化

  return TRUE;
}
//見易さのために、全角スペースを使って...続きを読む

Q_tcscpy_s(wcscpy_s)の第二引数って

http://msdn.microsoft.com/ja-jp/library/td1esda9%28VS.80%29.aspx

を見て、たとえば以下のような関数を書いたとします。

TCHAR* fn;

void OMG(LPCTSTR c){

int bytes( ( _tcslen(c) + 1 )*sizeof(TCHAR) );
if ( fn = (TCHAR*)malloc( bytes ) ) _tcscpy_s( fn, bytes, c ); //実行しないでください
else return;

/* fnを使用 */

free(fn); fn=0;

}


これ、マルチバイトだと正常に出来るのですが
なぜかUnicodeだと落ちてしまいました。

第2引数の説明は

コピー先の文字列バッファのサイズ。

<英語版でも>
Size of the destination string buffer.


となっていますが、その上に

numberOfElements

って書いてあるのでまさかと思い
サイズではなく文字数に変えたら、どうも正常に動作するようになったようです。

とくに_sがつく関数は文字数だったりバッファサイズだったりまちまちな感がもともとあるのに、しかも
こういうところでこういうことがあると厳しいものがあるのですが
これは本当に誤植なのでしょうか?

また、かなり稀なケースであり本当に誤植だとしたら、MSDNの他の文字列操作関数には記述の誤りがあるものはありますか?

http://msdn.microsoft.com/ja-jp/library/td1esda9%28VS.80%29.aspx

を見て、たとえば以下のような関数を書いたとします。

TCHAR* fn;

void OMG(LPCTSTR c){

int bytes( ( _tcslen(c) + 1 )*sizeof(TCHAR) );
if ( fn = (TCHAR*)malloc( bytes ) ) _tcscpy_s( fn, bytes, c ); //実行しないでください
else return;

/* fnを使用 */

free(fn); fn=0;

}


これ、マルチバイトだと正常に出来るのですが
なぜかUnicodeだと落ちてしまいました。

第2引数の説明は

コピー先の文字...続きを読む

Aベストアンサー

C++のtemplateを使ったstrcpy_s,wcscpy_sは

template <size_t size>
errno_t strcpy_s(
  char (&strDestination)[size],
  const char *strSource
); // C++ only

template <size_t size>
errno_t wcscpy_s(
  wchar_t (&strDestination)[size],
  const wchar_t *strSource
); // C++ only

となっています。
これをみると、sizeは「配列数」ということになります。

ですので、「numberOfElements」のさす意味そのもので「要素の数」(≠文字数)という解釈になります。


ちなみに、Unicodeでも1文字2バイトとは限りませんので
一概に文字数ともいえません。
(サロゲート で検索してみてください。)


>TCHAR c[100];
>
>if ( fn = (TCHAR*)malloc( sizeof c ) ) _tcscpy_s( fn, >sizeof(c)/sizeof(TCHAR), c );
>
>とか
>_tcscpy_s( fn, 100, c );
まぁ、結果的にあっていますが、fnに格納するときにバッファが足りているかをみるのをcを使うのはよろしくないかなと。

>int len( _tcslen(c) + 1 );
>if ( fn = (TCHAR*)malloc( len*sizeof(TCHAR) ) ) _tcscpy_s( fn, len, c );
のほうがよいですね。
まぁ、cに格納されている文字列を新しい領域をmallocしてコピーするのであれば、_tcsdupで

TCHAR* fn = _tcsdup(c);

と記述できます。
http://msdn.microsoft.com/ja-jp/library/y471khhc%28VS.80%29.aspx

C++のtemplateを使ったstrcpy_s,wcscpy_sは

template <size_t size>
errno_t strcpy_s(
  char (&strDestination)[size],
  const char *strSource
); // C++ only

template <size_t size>
errno_t wcscpy_s(
  wchar_t (&strDestination)[size],
  const wchar_t *strSource
); // C++ only

となっています。
これをみると、sizeは「配列数」ということになります。

ですので、「numberOfElements」のさす意味そのもので「要素の数」(≠文字数)という解釈になります。


ちな...続きを読む

QCString から LPCTSTRの型に変換

visual studio 2013 VC++を使用していますが、WINDOWSの関数に渡すためにCString からLPCTSTRに変換する必要があります。実際にどのようにするのかわかりません。
例えば、以下のサンプルは他の質問コーナーの回答をアレンジしたものです

CString str = _T("ABC");
int siz = str.GetLength()+1;
LPCTSTR pszFName = new TCHAR[siz];
_tcscpy_s( pszFName, siz, str );

で変換するのですが
LPCTSTRからwchar_t*へ変換できませんとエラーがでます
_tcscpy_s()は使用できないのでしょうか

Aベストアンサー

>APIはCStdioFile の Open()でファイル名を与えるところ

APIではないようですが……。

http://msdn.microsoft.com/ja-jp/library/ee247566.aspx
ならば、そのままCStringの変数渡せば、よろしく処理してくれると思いますけど。

QCStringからchar*への型変換について教えてください。

以前の質問に

int型 → CString型/char型

がありましたが、

CString型をchar*型に変換する方法を
教えていただければありがたいです。

MSDNで「LPCTSTRキャスト」が説明されていましたが、
例が載ってないのでよくわかりませんでした。

よろしくお願いします。

Aベストアンサー

目的にもよりますが一時的にchar配列として使いたいならCString::GetBuffer()が利用できます。
char配列としての利用が終わったらCString::ReleaseBuffer()する必要がありますが。

直接CString内の文字列を扱う必要があるならCString::operator LPCTSTRで文字列ポインタが得られます。
ただし、CStringオブジェクトをいじると無効ポインタなる可能性があるので気をつけてください。

MSDNのMicrosoft Foundation Classリファレンス→CString→クラスメンバで確認してください。

QcharからLPTSTRへの変換方法

リストコントロールにchar型の変数の値を数値として表示させたいのですが、charからLPTSTRへの洗練された変換方法がよくわからないです。

char tempChar;
CString tempString;
tempString.Format("%s", tempChar);
LPTSTR lpsz = new TCHAR[tempString.GetLength()+1];
_tcscpy(lpsz, tempString);

こんなプログラムを考えてみたのですが、汚いような気がします。もっと簡単で洗練された変換方法はないのでしょうか?

Aベストアンサー

wsprintfを使ってはどうでしょうか?

char tmpChar = 100;//表示する数値
TCHAR buf[5];
wsprintf(buf, "%d", tempChar);


人気Q&Aランキング