Windowsユーザーのアイコンの取得方法(xp,2003,vistaおよび以上のバージョンのシステムの実装)

2772 ワード

一、考え方を得る


1.APIを呼び出す
2.レジストリから取得
3.ハードディスクから直接ファイルを読み込む

二、実現過程

  • API呼び出しについて:
  • ネットで資料を探して、ユーザーの顔を取得するAPIはshell32.dll下に2つSHGetUserPicturePathExSHGetUserPicturePathがあります.
    そのうちSHGetUserPicturePathExVista以下のシステムはサポートされておらず、APIのIDは810である.SHGetUserPicturePathXP以下のシステムはサポートされておらず、APIのIDはVista以上261、XPと2003は233である.
    SHGetUserPicturePathEx: function(pwszUserOrPicName: PWideChar;
    
                  sguppFlags: DWORD; pwszDesiredSrcExt: PWideChar;
    
                  pwszPicPath: PWideChar; picPathLen: UINT; pwszSrcPath: PWideChar;
    
                  srcLen: UINT): HRESULT; stdcall;
    
    SHGetUserPicturePath: function(pwszPicOrUserName: LPCWSTR;
    
                  sguppFlags: DWORD;pwszPicPath: PWideChar;
    
                  picPathLen: UINT): HRESULT; stdcall;
    

    テストの結果、SHGetUserPicturePathExWin 7で問題なく動作し、Vistaで失敗.SHGetUserPicturePathWin 7、Win 8、Vistaでは問題なくXPで失敗.△この失敗を今まで知らなかったのに、どうしたことか.
    XPの下では他の方法で解決する必要があります.
  • レジストリからの読み出しについて:
  • XP下の現在のユーザアバターの格納場所は、HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Hints\\PictureSource他のシステムのレジストリが一時的に見つかりません.
    しかし、レジストリで現在のユーザーのアイコンを取得できるかどうか、Administratorのアイコンを取得できるかどうかはまだテストされていません.だから私はプログラムでレジストリを使う方法がありません.
  • フォルダからの直接読み込みについて:
  • Xpでのユーザ画像格納位置はC:\Documents and Settings\All Users\Application Data\Microsoft\User Account Pictures\.bmpこのフォルダでは他のユーザの顔も見ることができる.
    Win 7、Vista以上はC:\Users\\AppData\Local\Temp\.bmpPS:ここでは、APIを呼び出して画像を取得したり、削除したりしても.bmpユーザーの顔を修正したりするテストもあります.この.bmpファイルはすべて自動的に復元・修正されます.だから、この書類が届かない心配はありません.しかし、ディスクファイルを直接読み取る場合、これは手動または他の削除(可能性は低い)される可能性がありますが、ファイルにアクセスできません.
  • 総じて:
  • まず,システムバージョンを判断する必要があり,XP以下のシステムにはユーザピクチャという機能は直接ない.
    XPと2003は,現在のユーザ名を直接読み出し,ユーザピクチャパスを構築し,フォルダを読み出してピクチャを取得する.(動的に取得できることが望ましいC:\Documents and Settings\All Users\Application Data\フォルダパスは、あくまでシステム変数ユーザが位置を変更できる)
    Vista以上ではAPI取得パスを呼び出し,ピクチャを読み出す.
  • もう一つ重要な問題は、16ビットbmpの読み取りについてです.

  • 16ビットbmpにパレットが欠けているため、この問題に注意しないと、最後に表示される画像の色が正しくありません.私はDelphiを使っているので、最後の解決策はGdiPlusを使って、bmpファイルをロードして再描画して解決します.もっと良い方法があれば教えてください.
    var  
    draw: IGPGraphics;
    image, pThumbnail: IGPImage;Bmp.PixelFormat := pf24bit;
    {......}
    Bmp.SetSize(65, 65);
    draw := TGPGraphics.CreateBmp.Canvas.Handle);
    Image := TGPImage.Create(userPicPath);
    pThumbnail := image.GetThumbnailImage(65, 65, nil, nil);
    draw.DrawImage(pThumbnail, 0, 0, pThumbnail.Width, pThumbnail.Height);
    {......}
    

    *2014/6/12に記載*