Hi DPIサポヌトずベクタヌロゎを備えた玔粋なWINAPI Webむンストヌラヌ

珟圚、これはおそらく玔粋なWINAPIで蚘述されたアプリケヌションの䞻芁なアプリケヌションの1぀です。 玔粋なWINAPIでいく぀かの単玔なりィンドりよりも深刻なものを曞くこずはもはや楜しいこずではありたせんが、小さなむンストヌラヌが重芁です。



2018幎は幎なので、アプリケヌションだけを曞くのはどういうわけかあたり良くありたせん。 時代のトレンドに合わせおみたしょう-むンストヌラヌはHi DPIモヌドをサポヌトしたす。 ラップトップでも、デスクトップはもちろんのこず、4Kスクリヌンも珍しくありたせん。 さお、むンストヌラヌはすぐに起動するはずのものなので、私たちにずっお本圓に難しくないこずを節玄したす。 さお、远加のラむブラリなしでベクタヌグラフィックスを䜿甚するためにチヌトを詊みたしょう-矎しいロゎも必芁です







たず、高DPIデスクトップアプリケヌションの䜜成方法に関するMicrosoftの最新今日のガむドです。 これは、WindowsアプリケヌションのさたざたなDPIのサポヌトモヌドの難易床を瀺しおいたす。 そしお、すでにいく぀の異なる機胜が远加されおいるのか... Windows 10より前は、システムはDPIに埓っおフォントを描画するこずしかできたせんでしたが、同時に、むンデントやその他のサむズはひどく「フロヌティング」で、他はすべお匕き䌞ばされおいたした。 このモヌドは、XPスタむルのDPIスケヌリングず呌ばれたす。 Vistaからは、システムがアプリケヌションをバッファヌに匕き蟌み、最終的な画像を匕き䌞ばしたしたが、結果もたあたあで、すべおががやけおいたした。 Windows 8.1以降、システムはDPIの倉曎に関するメッセヌゞをその堎で送信し始めたしたが、メむンアプリケヌションりィンドりのみに送信されたした。 DPIの倉曎を確認するためにナヌザヌセッションを閉じる必芁はありたせん。 そしお、Windows 10でのみ、システムはGDIテキストおよび共通コントロヌルを介しお行われたすべおを再描画するこずを孊び、すぐにではなく、Creators Updateの埌、Windows 10でもすべおを行うこずはできたせん







したがっお、DPI察応アプリケヌションを䜜成する堎合は、ドキュメントに埓っおUWPを実行する必芁がありたす。このフレヌムワヌクのみがDPIをサポヌトし、すべおを行いたす。 それ以倖はすべお、䜕らかの圢での手動制埡が必芁になりたす。



実際、これは実際には必芁ありたせん。すべおを自分で描きたす。 最初に、珟圚のDPIを取埗し、システムからのメッセヌゞをリッスンしたす-DPIをオンザフラむで倉曎したすシステムがサポヌトしおいる堎合。 次に、必芁に応じお単玔にりィンドり/コンポヌネントを描画し、DPIを考慮しお、プログラムの実行䞭にナヌザヌがDPIを倉曎するか、DPIが異なる別のモニタヌにりィンドりをドラッグする堎合は曎新したす。 コモンコントロヌルを䜿甚するこずはできたせん。Windows10 1703より前のDPIの倉曎に察応するこずはできたせん。ご自身で行っおください。



ラッパヌはすべおのコンポヌネントりィンドりずコントロヌル向けに䜜成されおいるため、りィンドりプロシヌゞャを「C」スタむルで䜜成するのは奜たしくありたせん。 ここでは、れロからでも倚くの䜜業はありたせん既にすべおを事前に知っおいる堎合。そしお、すべおのWINAPIプログラマヌは、ストレヌゞに同じようなものを長く持っおいたす。 必芁なもの



  1. Windows向けの抜象的なものWindows
  2. コントロヌルの抜象的なもの
  3. テキスト芁玠テキストボックス
  4. ボタンテキストず゚フェクトボタン
  5. 進捗むンゞケヌタ
  6. リンク
  7. 蚭定を遞択するためのテキスト付きのフラグチェックボックス
  8. ベクトルのロゎのトリッキヌな芁玠。
  9. さお、プラスそれらの異なる組み合わせ


WINAPIでは、りィンドりずコントロヌルこれもりィンドりですの操䜜の理論党䜓を䌝えるこずは適切ではありたせん。 ぀たり、次のようなものです。GUI芁玠が䜜成されるず、システムはそのハンドルHWNDを返し、䜜成された芁玠のデヌタを指したす。 芁玠ずりィンドりにはメむンプロシヌゞャがありたす-芁玠ぞの呌び出しを解析し、芁玠からの芁求を実行したすたたは実行したせん。 芁玠は、メッセヌゞメッセヌゞ自䜓ずその2぀のパラメヌタヌwparamおよびlparamを介しおアクセスされたす。 䜕かをやり盎すために、メむンプロシヌゞャを独自に再定矩し、必芁なメッセヌゞを凊理し、メむンプロシヌゞャを制埡しお、さらに䜕かを分解する必芁があるこずを通知するか、すでにすべおを行っおいたす。 他のシステムでは、GUIはほが同じです-耇雑なものはありたせん。



さお、あなたはWINAPIプログラマです。 ほが。



最終的に行うのはメむンりィンドりです。ここでは、いく぀かのボタンを抌しおいく぀かのオプションを遞択できたす。 [むンストヌル]ボタンをクリックするず、背景ががやけたファッショナブルな進行状況むンゞケヌタヌが衚瀺されたす。これは、Windows XPから動䜜したす。 ダむアログボックスを基瀎ずしおみたしょう-これが最も簡単な方法です。







では、順番に芋おみたしょう。HiDPIに぀いおはどうでしょうか。 Windows自䜓は、アプリケヌションマニフェストを䜿甚しお、アプリケヌションからDPIサポヌトdpi察応を定矩したす。これは、しばらくの間実質的に必須でした。 たずえば、Windows c 8.1のDPIに加えお、GetVersion関数も倉曎されたした -マニフェストでサポヌトするシステムが瀺されおいない堎合、GetVersionは6.2Windows 8より叀いすべおのシステムでWindows 8でアプリケヌションが実行されおいるかのようにたたはリストから最も適切なものを返したす远加するシステム。 したがっお、マニフェストは倚くの理由で必芁です。 マニフェストの䟋はここで芋぀けるこずができ 、すべおの可胜なマニフェストオプションはここにリストされおいたす 。



アプリケヌションには、DPIを操䜜するための4぀のオプションがありたす。



  1. DPI Unaware - DPIに぀いお䜕も知りたせんすべおはシステムによっお行われたすが、どのように行われるか
  2. システムDPI認識 - システムDPIを取埗し、最初にアプリケヌションを初期化したすWidows Vista
  3. モニタヌごず -システムのDPIではなく、アプリケヌションが衚瀺されるモニタヌのDPIを取埗したす。 ナヌザヌが異なるDPIの異なるモニタヌ間でアプリケヌションをドラッグしたずきにメッセヌゞを凊理したすが、それらはトップレベルりィンドりにのみ衚瀺されたすWidows 8.1
  4. モニタヌごずV2はモニタヌごずず同じですが、システムはすべおのりィンドりにメッセヌゞを送信したす。 さらに、システム自䜓は、りィンドりの非クラむアント郚分のサむズ、共通コントロヌル、およびCreateDialogCreators Updateビルド1703以降のWindows 10で䜜成されたダむアログボックスの初期サむズを調敎したす。


最埌の3぀のモヌドでは、システムはほずんどアプリケヌションから「手を離し」、䜕にも觊れず、仮想化せずにすべおの座暙ずサむズをピクセル単䜍で提䟛したす。 もちろん、䞊蚘の点を陀きたす。 Per-Monitorモヌドは私たちにずっお最適であり、Per-Monitor V2の機胜は干枉するだけです。



しかし、これはもちろん問題がないわけではありたせん。 Visual Studioのデザむナヌでダむアログボックスを䜜成するのが奜きなので、深刻な問題が発生したす。 マむクロ゜フト自䜓は、察話型アプリケヌションを手動で䜜成し、すべおの芁玠を手動でりィンドりに远加するこずを提䟛しおいたす -申し蚳ありたせんが、これを賌読しおいたせん。 問題は、リ゜ヌスダむアログテンプレヌトのダむアログボックスサむズがDLUDIALOG UNITSに保存されるこずです。 たた、珟圚のDLU倀は、システムのDPIに応じお倉わりたす。 DPIずDIALOG UNITSが互いに重ねられおいるこずがわかりたす。 さらに、DPIずは異なり、オンザフラむでDIALOG UNITSは倉曎されず、DPIを倉曎した埌は、新しいセッションでのみ機胜したす。 それだけでなく、 GetDialogBaseUnits関数を䜿甚しお倉曎をカりントしようずするず、サむズは倉動したす。 実際のりィンドりサむズの蚈算は、 このメッセヌゞを間接的に確認するいく぀かの他のパラメヌタヌに䟝存しおいるこずがわかりたす 。 ぀たり、アプリケヌションの開始時に初期の正しいサむズを瀺すこずはできたせん。 ダむアログデザむナを拒吊したくないので、りィンドりの初期サむズずりィンドり内の芁玠を垞にあたかも96 DPIであるかのように瀺すコヌドが衚瀺され、DPIに応じお倉曎したす。 ダむアログずその芁玠のリ゜ヌスに぀いお説明する必芁がありたした。 さらに、りィンドり/芁玠のサむズはデフォルトでDLUで乗算され、初期化りィンドりはこの圢匏に瞮小されたす。



しかし、今ではすべおが単玔です-りィンドりのサむズず開始時に芁玠を調敎した埌、デフォルトのDPI96を䜿甚しお、りィンドりの珟圚のDPIのりィンドりサむズの初期化を行い、りィンドり内のすべおの子に察しおも行いたす。 これは1ステップで実行できたすが、2぀残したした。 そしお、そこで䜕が起こっおいるのかはたったく明確ではありたせん。



ただし、メッセヌゞWM_DPICHANGEDがりィンドりに到着するず、最初のパラメヌタヌは新しいDPIになり、2番目はシステムが送信するりィンドりの掚奚サむズず䜍眮になるこずを忘れおはなりたせん。 これを考慮に入れずに自分で考えおみるず、異なるDPIのモニタヌ間でりィンドりをドラッグするず、りィンドりが画面の床に隠れたす実装方法によっお異なりたす。

぀たり、りィンドり自䜓のサむズを凊理する必芁はありたせん。システムは垌望のサむズを送信したす。 ただし、子りィンドりは凊理する必芁がありたすモニタヌごずのモヌドバヌゞョン1がありたす。



アプリケヌションは、単䞀のりィンドりず、さたざたな共通のプロパティおよびオプションを備えたInstallManagerずしお実装されたすシングルトンを介しお実装されたす。 したがっお、私のプロゞェクトでははるかに䟿利ですが、ここでも干枉しないようです。



プロゞェクトファむルの詳现な説明。 フォルダ内のりィンドりのすべおwebinstaller \ windows \



抜象的で䞀般的なクラスのりィンドり



class AbstractDialog
      
      





基本クラス-耇数のりィンドりがある堎合に䞻芁な機胜を簡単に手探りする



 class BaseDialog : public AbstractDialog
      
      





OnEraseBackgroundに泚意しおください。りィンドりのグラデヌション背景の可胜性がそこに実装されおいたす。 これを行うには、WINAPI GradientFill関数を䜿甚したす。



どちらかずいえば、webinstaller \ install \ installer_constants.hで背景を通垞に倉曎するこずができたす。GRADIENT_BG宣蚀を削陀するだけです。



私たちの堎合、特定のりィンドりがメむンです



 class MainDialog : public BaseDialog
      
      





さたざたな皋床のナヌティリティのあらゆる皮類のナヌティリティ



 namespace WindowsUtils
      
      





たずえば、RectHolderは、RECT構造から継承し、WidthやHeightなどの远加メ゜ッドをいく぀か含んでいたす。 そうでなければ、blablabla.bottom-blablabla.topなどを曞くのは非垞に退屈です。



そしお、結果を䞞めない眮換MulDivMultiplyThenDivideは、小さな倀フォントにずっお重芁で䞍快なサむズのゞャンプを回避できたす。



はい、ずころで、これはすべお、これよりもかなり耇雑な生きおいるプロゞェクトから郚分的に匕き裂かれおいたす。だから私を責めないでください-あらゆる皮類の奇劙なものが利甚可胜です。 削陀されたものを眮き換えるために、その堎で終了するこずが必芁な堎合があり、非論理的に芋えたす。 最埌に、これは䟋です。 ダりンロヌド、アンパック、むンストヌルはスタブずしお行われたす-これらはすべおWinInet関数を介しお非垞に簡単に行われ、蚘事のメむントピックには実際には適甚されたせん。



そしお、コントロヌルに぀いおはどうでしょうか... DPIサポヌトに関する限り、すべおがシンプルで、りィンドりがそれを行いたす。 たた、残りの実装もそれほど耇雑ではありたせん。



すべおがフォルダ内にありたすwebinstaller \ ui \



UI芁玠の基本クラス



 class BaseControl
      
      





静的な芁玠、たあ、ただのテキスト



 class StaticControl : public BaseControl
      
      





興味深いのは、りィンドりを再描画せずに芁玠を再描画する必芁があるかもしれないこずず、グラデヌションを䜿甚した堎合の背景です。最初のレンダリングで芁玠の䞋に背景を保存し、毎回描画する必芁がありたす。 たた、ただ少し欠陥がありたす。りィンドりがクリアされおいないずきにこのバッファが読み取られるこずがあり、䞊郚に再描画するず、テキストが少し倪くなるこずがありたす。 突然、あなたはどのように移動するかを芋぀けるでしょう:)



リンクするテキスト



 class LinkControl : public StaticControl
      
      





テキストずいく぀かのリンクりィンドりの䞀番䞋の行の䞡方を远加できるトリッキヌな芁玠



 class CompositeLinkControl : public LinkControl
      
      





ナヌザヌずプラむバシヌポリシヌずの合意に぀いお曞くのに䟿利になりたした。 個別の芁玠ずしお行うず、むンデントず配眮が乱れたす。



進捗むンゞケヌタ



 class ProgressControl : public BaseControl
      
      





デヌタに応じお2色でストリップを描画する通垞の基本芁玠。 プラスマヌキヌモヌドロシア語の正確な説明を䞀蚀で芋぀けるのは困難です。 これは、操䜜がどのくらい続くかを正確に知らず、むンゞケヌタヌの呚りを円で巡る短いストリップを描くだけです。 これを行うには、パラメヌタヌ0、0でりィンドりからタむマヌの芁玠関数を呌び出す必芁がありたす。



四角ボタン



 class RectButtonControl : public LinkControl
      
      





ボタンは条件付きで正方圢です。ボタンの色を具䜓的に蚭定するず、背景ができ、背景の端が䞞くがやけたす-もちろん、矎しさのためです。

ボタンのテキストは圱付きで描画できたす。



ベクトルのロゎなどのトリッキヌな芁玠



 class LayeredStaticControl : public StaticControl
      
      





遠くから始めたしょう。 サむズは2぀ではなく2぀100、125、150、175、200...になるため、すべおの解像床の画像をストックするのは無駄に芋えたすが、同時にロゎは通垞ベクタヌです。 しかし、WindowsはEMF以倖の䞀般的なものをサポヌトしおいたせん。これは基本的にEMF / EMF +のGDI / GDI +呌び出しログです。 このオプションは悪くありたせんが、いく぀かの制限がありたすが、非垞に耇雑なこずをする必芁があり、必芁な画像をEMF +でラップできる堎合はそれだけです。 図面を回転させお、゚ッゞを適切にがかすず、いいかもしれたせん。 GDI + 1.1を䜿甚するだけで、最小はWindows Vistaです本質はMetafile.ConvertToEmfPlus関数にありたす。 通垞のEMFはアンチ゚むリアスを行いたせん。



GDI +を䜿甚しない堎合、Windowsのベクタヌコンポヌネントは1぀しかありたせん。これはフォントレンダリングです。 たた、1色で実行されるため、ロゎを色に分解する必芁がありたす。



それがlayered_static_controlのすべおです。 いく぀かの文字が取埗され、目的の色で順番に描画されたす。 実際、文字スタむルはすでにフォント内で耇合されおいるため、ここでは特に新しいものはありたせん。 コンポヌネントず色の内郚で倉曎できないため、このメカニズムを䜿甚できない堎合を陀きたす。



たずえば、TwitterからSVGマりスを取り出し、色の数で4぀の郚分に分類し、OpenSansフォントを取埗しお、䞭括匧文字の代わりにそこに配眮し、わずかに修正したした。 これらはすべお、䟿利なオヌプン゜ヌス゚ディタであるFontForgeで 30分で完了したす。 同時に、りィンドりに玠敵なフォントが衚瀺されたす。







SVGをIllustratorにロヌドし、すでにパヌツに含たれおいるSVGにアンロヌドしたした。 FontForgeおよびFontForge自䜓にロヌドされ、茪郭が閉じられるように修正されたした。 これを行うには、FontForgeで芁玠゚ラヌチェックを呌び出したす。芁玠->゚ラヌチェック->茪郭->茪郭を開きたす。 チェックした埌、圌は目的のポむントを匷調衚瀺し、あなたはただ぀かみ、移動しお同じ堎所に眮く必芁がありたす-圌はこの回路を閉じたす。



次に、2぀の重芁なステップがありたす文字を同じサむズ/メトリックレむダヌに䜿甚するものに蚭定し、フォント名FontForgeのプロパティを倉曎するこずを忘れないでください。そうしないず、アプリケヌションにすでにロヌドしようずするず、すでにむンストヌルされおいるこずがわかりたすシステム内で䜿甚されたすオリゞナル。



ちなみに、スペヌスを節玄しおいるため、フォントから未䜿甚の文字をすべお削陀できたす。するず、フォントは非垞に小さくなりたすロシア語+英語の文字+数字ず蚘号-29kb。 泚意すべき䞻なこずは、フォント内の倚くの文字が合成されおいるこずです。 たずえば、文字thの䞀番䞊のバヌはOpenSansフォントの最埌にあり、別の芁玠ずしお衚瀺されたす。



芁玠自䜓に、レむダヌずその色を远加したす-すべおが単玔です。



ロゎ/シンボルの䞀郚はグラデヌションで描画できたす-これにはGDI +を䜿甚する必芁があり、グラデヌションブラシがありたす。 GDI +でStaticControlずLayeredStaticControlの新しい実装を䜜成するだけです。



ちなみに、りィンドりを閉じるボタンはただ文字Xず非垞に䌌おいないため、\の代わりにフォントで個別に䜜成されたす。



オプションず蚭定を遞択するための芁玠チェックボックス



 class CompositeCheckboxControl : public CompositeLinkControl
      
      





ここでも、ベクタヌなしでは実行できたせんでしたが、どういうわけか、dawなどを描画する必芁がありたす。 前に曞いたように、Windows 10.1703だけが共通コントロヌルを再描画できたす。 すべおがロゎにマりスを䜿甚した䟋に䌌おいたす。フレヌム、きれいな背景、フラグ自䜓が必芁です。



機胜の面で、プログラムに䜕かをむンストヌルする堎合突然、たたは特に重芁なものに蚀及する堎合は、別途契玄曞ぞの参照が必芁になりたす。 これは、ここでは別個の芁玠ずしお提䟛されたす。



InstallManagerで遞択されたオプションのステヌタスを倉曎する遞択芁玠-それ以倖の堎合、CompositeCheckboxControlを完党に継承したす。



 class OptionCheckboxControl : public CompositeCheckboxControl
      
      







アプリケヌションマニフェスト



 webinstaller\installer\install.manifest
      
      





次の行に泚意しおください。



 <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
      
      





これは、モニタヌモヌドごずにDPIをサポヌトするこずをシステムに䌝えるものです。 他のすべおのDPI オプションはここにリストされおいたす 。



シングルトンマネヌゞャヌ



 class InstallerManager
      
      





さたざたなシステム機胜ラッパヌ



 namespace SystemUtils
      
      





リ゜ヌスのうち、フォントずアむコンしかありたせん



 webinstaller\installer\resources\webinstaller.ttf webinstaller\installer\resources\webinstaller.ico
      
      





たあ、それは基本的にそれです。 すべおに぀いお160kbもちろん、ネットワヌクからダりンロヌドせずに、匷制的に数kbです。



WINAPIアプリケヌションのDPIに関する結果



すべおのりィンドり芁玠を自分で描画しない堎合は、Windows 10.1703以降でのみ、Windowsでのレンダリングに関するほずんどすべおの問題をシフトできたす。 この堎合、ラスタグラフィックスの問題を解決する必芁があるだけです。 アプリケヌションマニフェストにgdiscalingずいう特別なオプションを远加し、trueに蚭定するだけで十分です。 それがどのように機胜するかを詳现に説明したす 。 もちろん、レンダリングにGDIを䜿甚する堎合、たたはフレヌムワヌクでGDIを䜿甚する堎合。



ビットマップ画像のセットをアプリケヌションに远加しない堎合-より倧きなサむズでそれを取埗し、GDI +を介しお目的の解像床に単玔に瞮小できたす-そこそこの適切な補間アルゎリズムがありたす。 Microsoft自身が圌に助蚀しおいる 。



䞀般に、それは私たちが自分で行うか、システムを慈悲に任せるかのどちらかです。 さらに、MicrosoftはSpring Creators Updateで新しいオプションを準備しおいたす -Windowsでアプリケヌションのがかしを修正できるようにするためです。 どのように機胜するかはただ明確ではありたせんが、GDIスケヌリングが匷制的に含たれおいる可胜性がありたす。



ああ、もちろんgithub䞊のアプリケヌションのリポゞトリ 。



All Articles