Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows Imaging Component を使って背景画像を読み込み、透過描画対応 #683

Merged
merged 5 commits into from
Dec 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sakura_core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ LIBS= \
-limagehlp \
-lshlwapi \
-lwinmm \
-lwindowscodecs \
-lmsimg32 \
-mwindows \
$(MYLIBS)

Expand Down
120 changes: 66 additions & 54 deletions sakura_core/doc/CEditDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#include <string.h> // Apr. 03, 2003 genta
#include <memory>
#include <OleCtl.h>
#include <wincodec.h>
#pragma comment(lib, "windowscodecs.lib")
#include <wrl.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

レビューコメントではないですが

この3行は StdAfx.h に移動したいな、って思ってます。

Copy link
Contributor Author

@beru beru Dec 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <string.h> // Apr. 03, 2003 genta
#include <memory>

 γ  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ヽ
 |彡(゚)(゚) 彡(゚)(゚) あれ?ワイらは? |
  乂_______________ノ

#include <OleCtl.h>

 γ  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ヽ
 | 彡(゚)(゚) ここにいても いいの? |
  乂______________ノ

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「移動」じゃなくてもいいっすよ。

まぁ #include <string.h> は削りたいです。

#include "doc/CEditDoc.h"
#include "doc/logic/CDocLine.h" /// 2002/2/3 aroka
#include "doc/layout/CLayout.h" // 2007.08.22 ryoji 追加
Expand Down Expand Up @@ -317,61 +320,70 @@ void CEditDoc::SetBackgroundImage()
GetInidirOrExedir( &fullPath[0], &path[0] );
path = fullPath;
}
const TCHAR* ext = path.GetExt();
if( 0 != auto_stricmp(ext, _T(".bmp")) ){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ: extが"bmp"と一致する場合、Bitmapを読み込んで都合よく変換する

HANDLE hFile = ::CreateFile(path.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
if( hFile == INVALID_HANDLE_VALUE ){
return;
}
DWORD fileSize = ::GetFileSize(hFile, NULL);
HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, fileSize);
if( hGlobal == NULL ){
::CloseHandle(hFile);
return;
}
DWORD nRead;
BOOL bRead = ::ReadFile(hFile, GlobalLock(hGlobal), fileSize, &nRead, NULL);
::CloseHandle(hFile);
hFile = NULL;
if( !bRead ){
::GlobalFree(hGlobal);
return;
}
::GlobalUnlock(hGlobal);
{
IPicture* iPicture = NULL;
IStream* iStream = NULL;
//hGlobalの管理を移譲
if( S_OK != ::CreateStreamOnHGlobal(hGlobal, TRUE, &iStream) ){
GlobalFree(hGlobal);
}else{
if( S_OK != ::OleLoadPicture(iStream, fileSize, FALSE, IID_IPicture, (void**)&iPicture) ){
}else{
HBITMAP hBitmap = NULL;
short imgType = PICTYPE_NONE;
if( S_OK == iPicture->get_Type(&imgType) && imgType == PICTYPE_BITMAP &&
S_OK == iPicture->get_Handle((OLE_HANDLE*)&hBitmap) ){
m_nBackImgWidth = m_nBackImgHeight = 1;
m_hBackImg = (HBITMAP)::CopyImage(hBitmap, IMAGE_BITMAP, 0, 0, 0);
}
}
}
if( iStream ) iStream->Release();
if( iPicture ) iPicture->Release();
}
}else{
m_hBackImg = (HBITMAP)::LoadImage(NULL, path.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ: extがbmpと一致しない場合、Bitmapとして「そのまま」読み込む

背景画像に指定したbmpファイルを削除できないのはこれが原因・・・(削られてますなw

}
if( m_hBackImg ){
BITMAP bmp;
GetObject(m_hBackImg, sizeof(BITMAP), &bmp);
m_nBackImgWidth = bmp.bmWidth;
m_nBackImgHeight = bmp.bmHeight;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ:bitmapを読込できた場合、サイズ情報を取得している

読込できなかった場合の考慮はなし、メッセージもなし。

if( 0 == m_nBackImgWidth || 0 == m_nBackImgHeight ){
::DeleteObject(m_hBackImg);
m_hBackImg = NULL;
}

using namespace Microsoft::WRL;
ComPtr<IWICImagingFactory> pIWICFactory;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ: usingに注意。ComPtrの使い方はATL/MFCのCComPtrとほぼ同じです。
Atl masterの人が「違う!」と言うかもしれませんがほぼ同じです。

HRESULT hr;
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pIWICFactory));
if( FAILED(hr) ) return;
ComPtr<IWICBitmapDecoder> pDecoder;
hr = pIWICFactory->CreateDecoderFromFilename(
path.c_str(),
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder);
if( FAILED(hr) ) return;
ComPtr<IWICBitmapFrameDecode> pFrame;
hr = pDecoder->GetFrame(0, &pFrame);
if( FAILED(hr) ) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ: WICは昔windows xpに搭載されていた「イメージング」の基盤になってる技術です。パラパラ漫画のように複数画像をアニメーション表示できる画像フォーマットに対応するためWICの画像データは複数イメージ前提で構成されています。pDecoder->GetFrame(0, &pFrame) は先頭の画像情報を読んでる、ということになります。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

画像ファイルフォーマットによっては複数フレームの絵が入るのでそれに対応しているAPIですね。

WIC自体がいつから登場したのは記憶に無いですが確か Vista 以降ですね。結局芽が出なかった WinFS 以外にも色んなコンポーネントを裏では準備していたんでしょうね。

//WICPixelFormatGUID pixelFormat;
//hr = pFrame->GetPixelFormat(&pixelFormat);
//if( FAILED(hr) ) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ: WICで画像のピクセル形式を確認するための標準的なコードがコメントアウトされています。

フォーマット変換するので変換前を取得してみたけど、変換前フォーマットが要らなかった、ということかと思っています。あっても邪魔にはならないからこのままでいいかな~とか。

Copy link
Contributor Author

@beru beru Dec 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

アルファチャンネルを含んでいない画像フォーマットな場合には 24bit DIB で済ませて、AlphaBlend による描画ではなくて従来通りの BitBlt で済ますのが良いと思いますがその判定を少ない記述で済ます方法が分からなくて諦めました。ここのコメントはその名残です。

ComPtr<IWICFormatConverter> pConverter;
pIWICFactory->CreateFormatConverter(&pConverter);
if( FAILED(hr) ) return;
hr = pConverter->Initialize(
pFrame.Get(),
GUID_WICPixelFormat32bppPBGRA,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ:WICのフォーマット定数はGUIDで、色々あります。
ここの例だと32bitプログレッシブBGRA(RGBではない)ですね。
intel cpuはlittle endianですが、little endian前提で 0xAARRGGBB という感じに色定義できるのがBGRA形式です。

Copy link
Contributor Author

@beru beru Dec 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PBGRA の P はプログレッシブではなく、premultiplied alpha を示している文字かと思います。Progressive と Djent ともまた違った関係性です。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PBGRA の P はプログレッシブではなく、premultiplied alpha を示している文字かと思います。Progressive と Djent ともまた違った関係性です。

かなり長いこと勘違いしてました。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なおAPI関数の AlphaBlend が premultiplied alpha な入力を使う仕様という事を当初把握していなくて、このPRの最初のコミットではきちんと表示されていませんでした。

自分や arigayas さんが貼り付けたスクリーンショット(自分が貼ったのは今はもう修正済み)を見て半透過部分が正しく描画されてなくて問題に気づきました。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

見映えに関する修正は通りやすいですが、
見映えが変わらない変更は了解を取り付けるのに苦労します。
WIC導入は単体で大きなインパクトを与える変更です。
が、単体で入れようとすると実質何にも変わらないので入れづらいと思ってました。

描画のとこは最悪「あとで修正」も容易なのでスルーしてました・・・

WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeCustom);
if( FAILED(hr) ) return;
UINT width, height;
hr = pConverter->GetSize(&width, &height);
if( FAILED(hr) ) return;
BITMAPINFO bminfo = {0};
BITMAPINFOHEADER& bmih = bminfo.bmiHeader;
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = (LONG)width;
bmih.biHeight = -(LONG)height;
bmih.biPlanes = 1;
bmih.biBitCount = 32;
bmih.biCompression = BI_RGB;
HDC hdcScreen = GetDC(NULL);
if( !hdcScreen ) return;
void *pvImageBits = NULL;
m_hBackImg = CreateDIBSection(hdcScreen, &bminfo, DIB_RGB_COLORS, &pvImageBits, NULL, 0);
ReleaseDC(NULL, hdcScreen);
if( !m_hBackImg ) return;
UINT lineStride = 4 * width;
hr = pConverter->CopyPixels(
NULL,
lineStride,
lineStride * height,
(BYTE*)pvImageBits);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ:変換済みビットマップからpixelデータを取り出してDIBSectionのビット領域にコピーしています。
ビット領域のサイズは 4bytes × 幅 × 高さになっています。
細かいことを語ると「猫でも分かる(ry」の1章分くらい説明することがたくさんありますので詳細は略。

if( FAILED(hr) ){
::DeleteObject(m_hBackImg);
m_hBackImg = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ:ビット領域をコピーできなくても、CreateDIBSectionで作ったビットマップは削除が必要です。

}
m_nBackImgWidth = (int)width;
m_nBackImgHeight = (int)height;
}

/* 全ビューの初期化:ファイルオープン/クローズ時等に、ビューを初期化する */
Expand Down
2 changes: 1 addition & 1 deletion sakura_core/typeprop/CPropTypesWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ INT_PTR CPropTypesWindow::DispatchEvent(
case IDC_BUTTON_BACKIMG_PATH_SEL:
{
CDlgOpenFile::SelectFile(hwndDlg, GetDlgItem(hwndDlg, IDC_EDIT_BACKIMG_PATH),
_T("*.bmp;*.jpg;*.jpeg"), true, EFITER_NONE );
_T("*.bmp;*.jpg;*.jpeg;*.png"), true, EFITER_NONE );
}
return TRUE;
// From Here Sept. 10, 2000 JEPRO
Expand Down
22 changes: 16 additions & 6 deletions sakura_core/view/CEditView_Paint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "StdAfx.h"
#include <vector>
#include <limits.h>
#pragma comment(lib, "Msimg32.lib")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ:これも StdAfx.h に移動したいな~。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

プリコンパイル済みヘッダに変更が入るといったん全体のビルドが必要になるので抵抗感があります。

自分は何か別の cpp ファイルを1つ作って、#pragma comment(lib, "hoge.lib") の記述はそこに纏めてしまう運用を過去に取っていました。

プロジェクトのプロパティ(Linker, Input)で指定する方法は、VS2005 とかの頃は追加すると全体のビルドが必要になってしまってうげーっと思いましたが VS2017 で試してみるとそんな事無いですね。記憶違いでしょうか…。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#pragma comment(link の仮置き場として最も適切なのはエントリポイントがあるcppだと思います。現状でコモンコントロールの埋め込み命令がstdafx.hにあるので、とりあえずそこに合わせに行くのが妥当かな?と思ってます。

「あるべき姿は winmain.cpp に移動」と言ってます・・・。

あるべきを語り出すと面倒くさいので放置でもいいかな、とかも思ったり。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#pragma というコンパイラ依存の記述に「あるべき場所」が存在するということに納得がいっていません。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StdAfx.h の中身は「ほぼすべてのソースファイルが必要とする基礎的なヘッダファイル」だと理解しています。画像関係は違う気がします。

Copy link
Contributor

@berryzplus berryzplus Dec 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#pragma というコンパイラ依存の記述に「あるべき場所」が存在するということに納得がいっていません。

#pragma だけならどこでもいいと思います。#pragma comment(link なら話が別です。
実際にリンクが必要なコードと一緒に記述するか、メイン関数を含むファイルに書くべきだと思います。

StdAfx.h の中身は「ほぼすべてのソースファイルが必要とする基礎的なヘッダファイル」だと理解しています。画像関係は違う気がします。

StdAfx.h にはプログラムが必要とするヘッダのうち、滅多に変更されないものを記述します。プログラム内で一度でも利用され、かつ、滅多に変更されないヘッダなら、StdAfx.h に指定する意味があります。反対に、わずかでも変更される余地のあるヘッダは StdAfx.h から参照すべきではありません。

たくさんのソースコードで参照されるかどうかは関係ないと思います。
https://docs.microsoft.com/he-il/cpp/build/reference/creating-precompiled-header-files?view=vs-2017

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#pragma comment(lib, "Msimg32.lib") 等の記述場所ですが、エントリポイントがある cpp ファイルに記述するのが適切なのかどうか自分には分かりませんが、どこかのファイルにまとめて記述するのは有りだと思います。StdAfx.h は変更すると全体のビルドが発生するので抵抗感がありますが…。

例えば、Msimg32.lib を追加した理由は AlphaBlend 関数の為ですがこの関数を複数の cpp ファイルに今後記述するかもしれないのでそうなった場合にじゃあどっちに #pragma comment(lib, "Msimg32.lib") を書くべきなのか、とか考えると結論が出しにくいと思うので。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stdafx.h 中に記述されているマニフェストの依存関係指定ですが、Visual Studio 2005 から使えるようになったみたいですね。

VisualStudio 2018 でMFCアプリを新規作成したところ下記の記述が Stdafx.h に入る事を確認しました。

#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

なお以下がサクラエディタの Stdafx.h ファイル中の記述です。

#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif

Intel の Itanium プロセッサはそもそも誰も動作確認していないので記述を打ち切って良いと思います。

https://blogs.msdn.microsoft.com/oldnewthing/20070531-00/?p=26623

に書かれてましたがそもそも processorArchitecture はワイルドカード指定で良いみたいです。

#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

そして Stdafx.h ファイルでなくても問題無いので、今後 #pragma comment(linker, .... の記述が増える事を考えると将来的に Stdafx.h から別のファイルに移動しても良いかも知れないと思いました。ただ Stdafx.h ファイルをいじると全体のビルドが必要になるので、Stdafx.h ファイルに何か記述を追加する必要が生じた時についでに、でも良いと思います。全体のビルドもサクラエディタはそこまで重いとは思いませんが…。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stdafx.h 中に記述されているマニフェストの依存関係指定ですが、Visual Studio 2005 から使えるようになったみたいですね。

マニュフェスト自体が vista 以降だった気が。
windows xp もサービスパックを当てればマニュフェストを認識できますが。

Intel の Itanium プロセッサはそもそも誰も動作確認していないので記述を打ち切って良いと思います。

これは提案すれば反対する人いないと思います。
IA64アーキテクチャで動かすことは誰も想定してないはず。
これってどういうものですか?って質問はあるかもですが(笑

https://blogs.msdn.microsoft.com/oldnewthing/20070531-00/?p=26623

に書かれてましたがそもそも processorArchitecture はワイルドカード指定で良いみたいです。

一度どこかで話題に出た気がします。

ワイルドカードを指定した場合には、
プログラム起動時に「Win32サブシステム」が妥当なアーキテクチャに読み替えてくれます。
この読み替えのオーバーヘッドがどれくらいあるかは分かりません。
指定できるものは指定したままにしよう、と提案した記憶があります。

#pragma comment(linker#pragma comment(link は別物です。

#pragma comment(linker ・・・ ソースコードにリンカオプションを埋め込む
#pragma comment(link ・・・ ソースコードに依存ライブラリ指定を埋め込む

いずれもプロジェクト設定で指定できますが、プリプロセッサで内容を変えられるのが #pragma を使うメリットです。

リンカオプションは矛盾した指定をしてしまう可能性があるので多用すべきでない気がします。
どこか一か所にまとめて記述するようにしたら矛盾させるリスクを下げられるんじゃないかと思っています。
これは根拠がある話ではありません。なんとなく、そう考えているだけです。

#include "view/CEditView_Paint.h"
#include "view/CEditView.h"
#include "view/CViewFont.h"
Expand Down Expand Up @@ -198,6 +199,8 @@ void CEditView::DrawBackImage(HDC hdc, RECT& rcPaint, HDC hdcBgImg)
#else
CTypeSupport cTextType(this,COLORIDX_TEXT);
COLORREF colorOld = ::SetBkColor(hdc, cTextType.GetBackColor());
MyFillRect(hdc, rcPaint);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ: MyFillRect は指定された矩形を現在の背景色で塗り潰す独自関数です。
透過実装を行うなら、この辺を中心に見直しかけることになると思います。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GDI 使った描画から Direct2D 使った描画に切替がぼちぼち必要ですね。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

切替というかGdi描画機構は可能な限り残したいなぁ・・・と思ってます。

テキスト描画方法の変更に着手できるのは年明け以降になる見込みですが、直接directwrite実装に移行させたい所存です。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

直接 GDI や Direct2D, DirectWrite の API を叩かないでクラスで包んでから呼び出すようにするのが良いと思いますが、空想と現実の間には距離がありますね。要求するニーズを満たすクラスの設計も実装も大変だし面倒だし。


const CTextArea& area = GetTextArea();
const CEditDoc& doc = *m_pcEditDoc;
const STypeConfig& typeConfig = doc.m_cDocType.GetDocumentAttribute();
Expand Down Expand Up @@ -279,20 +282,29 @@ void CEditView::DrawBackImage(HDC hdc, RECT& rcPaint, HDC hdcBgImg)
CMyRect rcBltAll;
rcBltAll.SetLTRB(INT_MAX, INT_MAX, -INT_MAX, -INT_MAX);
CMyRect rcImagePosOrg = rcImagePos;
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0xFF;
bf.AlphaFormat = AC_SRC_ALPHA;
for(; rcImagePos.top <= nYEnd; ){
for(; rcImagePos.left <= nXEnd; ){
CMyRect rcBlt;
if( ::IntersectRect(&rcBlt, &rc, &rcImagePos) ){
::BitBlt(
int width = rcBlt.right - rcBlt.left;
int height = rcBlt.bottom - rcBlt.top;
::AlphaBlend(
hdc,
rcBlt.left,
rcBlt.top,
rcBlt.right - rcBlt.left,
rcBlt.bottom - rcBlt.top,
width,
height,
hdcBgImg,
rcBlt.left - rcImagePos.left,
rcBlt.top - rcImagePos.top,
SRCCOPY
width,
height,
bf
);
rcBltAll.left = t_min(rcBltAll.left, rcBlt.left);
rcBltAll.top = t_min(rcBltAll.top, rcBlt.top);
Expand Down Expand Up @@ -336,8 +348,6 @@ void CEditView::DrawBackImage(HDC hdc, RECT& rcPaint, HDC hdcBgImg)
if( y3 < y4 ){
rcFill.SetLTRB(x1,y3, x4,y4); MyFillRect(hdc, rcFill);
}
}else{
MyFillRect(hdc, rc);
}
::SetBkColor(hdc, colorOld);
#endif
Expand Down
2 changes: 1 addition & 1 deletion tests/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ elseif (MINGW)
list (TRANSFORM ALL_O REPLACE "\\.(cpp|rc)$" ".o")
target_link_libraries (${project_name} PRIVATE ${ALL_O})
endif ()
target_link_libraries (${project_name} PRIVATE winspool ole32 oleaut32 uuid comctl32 imm32 mpr imagehlp shlwapi winmm)
target_link_libraries (${project_name} PRIVATE winspool ole32 oleaut32 uuid comctl32 imm32 mpr imagehlp shlwapi winmm windowscodecs msimg32)