XPと2000で EM_GETSEL の動作が違う?!

先日の記事の件、よく調べてみたら、 XP と 2000で動作が違うことが判明。

Windows 9x系だと EM_GETSEL がUnicode系で動作しない件

XPは SendMessageA と SendMessageW でメッセージを使い分けているのに対して、 2000では、 オブジェクトの生成が、CreateWindowA だったか CreateWindowW だったかが判断して 分岐して値を変えてるみたい。

つまり、2000で、 SendMessageA と SendMessageW を混在させると、まともにプログラムが動かない

例えば、キー入力で反応がなかったり、オブジェクトが生成されなかったりという事態が生まれるわけですね。

というわけで、先日のコードこうした方がいいみたい

int EM_GETSELW(HWND hWnd,int *i,int *j){
  int k,l,m,n,m2,n2,ret;
  wchar_t pszUnicode[4],*pos;
  char pszMBCS[4];
  int nLen;
  ret=SendMessageW(hWnd,EM_GETSEL,(WPARAM)&m,(LPARAM)&n);
//  SendMessageA(hWnd,EM_GETSEL,(WPARAM)&k,(LPARAM)&l);
  k=m;
  l=n;
  if(GetVersion()&0xf<5)
  {
    ret=GetWindowTextLengthW(hWnd);
    pos=new wchar_t[ret+1];
    if(pos==NULL)return -1;
    GetWindowTextW(hWnd,pos,ret+1);
    for(m=n=0,m2=n2=-1;pos[m];m++,n+=lstrlenA(pszMBCS)){
      if(n==k)m2=m;
      if(n==l)n2=m;
      lstrcpynW(pszUnicode,pos+m,2);
      pszUnicode[1]=0;
      nLen = ::WideCharToMultiByte(CP_THREAD_ACP, 0, pszUnicode, 1, NULL,0, NULL, NULL );
      if(nLen>0){
        nLen = ::WideCharToMultiByte(CP_THREAD_ACP, 0, pszUnicode, 1, pszMBCS,nLen, NULL, NULL );
        if(nLen>0)pszMBCS[nLen]=0;
      }
      else *(short int*)pszMBCS=L' ';
    }
    if(n==k)m2=m;
    if(n==l)n2=m;
    ret=(m2&0xffff)|(n2<<16);
    delete []pos;
    if(i)*i=m2;
    if(j)*j=n2;
  }
  else{
    if(i)*i=m;
    if(j)*j=n;
  }
  return ret;
}

あ、くれぐれも SendMessageA(hWnd,EM_GETSEL,WPARAM,LPARAM) との混在コードは書かないように(笑)

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です