ObjReader Community
WIP => WIP => Topic started by: Patrice Terrier on May 28, 2017, 10:48:54 am
-
I have just completed the rough translation of the OTB PB's version to C++.
That was a rather long and tedious work to say the least...
I am now starting to debug the VS 2017 code, if ever you want to help, then you are very welcome. :)
The latest RELEASE CANDIDATE version is attached to this post.
The latest STANDALONE version is merging Andrey changes and mines altogether.
-
Andrey--
float rAlphaCoef;
for (y = 0; y < H; y++) {
for (x = 0; x < W; x++) {
rAlphaCoef = (float) (pBits[3] / 255.0f);
pBits[2] = (BYTE) (pBits[2] / rAlphaCoef);
pBits[1] = (BYTE) (pBits[1] / rAlphaCoef);
pBits[0] = (BYTE) (pBits[0] / rAlphaCoef);
pBits += 4;
}
}
This code, even if it looks strange, is correct to preserve the original PNG transparency, other way the transparency is grayed too much.
Take a snapshot on a white background to see the difference.
-
Andrey
Your code doesn't produce the correct result.
See the attached screen shot, top with yours, bottom with mine.
This is very obvious with the recycle bin, but also with the image reflection.
I want to have exactly the same color transparency that the original Recycle bin shown on the right part.
Yes, I see... rounding error... just use shift by 16, then will be ok
for (y = 0; y < H; y++)
for (x = 0; x < W; x++) {
if (bits->argbAlpha == 0)
bits->argb = 0;
else
{
ULONG rAlphaCoef = (255 << 16) / bits->argbAlpha;
bits->argbRed = (BYTE)(((ULONG)bits->argbRed * rAlphaCoef) >> 16);
bits->argbGreen = (BYTE)(((ULONG)bits->argbGreen * rAlphaCoef) >> 16);
bits->argbBlue = (BYTE)(((ULONG)bits->argbBlue * rAlphaCoef) >> 16);
}
bits++;
}
-
hmm.. i have no trouble with shift 8
greets
it will be on some values...
for example alpha=250, color=251... then instead of 0 you will get 255,
same with 251:252, 252:253, 253:254, 254:255, ...
if use shift by 16, then there is no this problem
test
int err = 0;
for (ULONG a = 0; a < 256; a++)
{
float rAlphaCoef = (float)((float)a / 255.0f);
ULONG uAlphaCoef = a ? ((255 << 8) / a) : 0;
for (ULONG c = 0; c < 256; c++)
{
BYTE n = (BYTE)(int)((float)c / rAlphaCoef);
BYTE m = (BYTE)(((ULONG)c * uAlphaCoef) >> 8);
if (n != m && abs(n - m) > 1)
wprintf(L"error: a: %03d; c: %03d [n: %05d, m: %05d] %i\n", a, c, n, m, ++err);
}
}
-
For the sake of compatibility with PB's OTB version
here is the one i shall use in OTB 64.
It has been modeled on those used in both GDImage and ObjReader when creating transparent OpenGL textures.
(Search for Mobj_CreateGLTextureFromFileEX in the ObjReader source code)
HBITMAP CreateDockIcon (IN WCHAR* zImgName, OUT long &imgW, OUT long &imgH) {
HBITMAP nRet = 0;
// Load image
LONG_PTR img = 0;
if (GdipLoadImageFromFile(zImgName, img) == 0) {
// Get the image height and width
GdipGetImageWidth(img, imgW);
GdipGetImageHeight(img, imgH);
HDC hDC = DisplayDC();
HDC ImgHDC = CreateCompatibleDC(hDC);
long UseImgH = imgH + (imgH / 2);
// We must deal with 32-bit to handle the alpha channel
HBITMAP hbmReturn = ZI_CreateDIBSection(hDC, imgW, UseImgH, 32);
SelectObject(ImgHDC, hbmReturn);
DeleteDC(hDC);
// Draw image
LONG_PTR graphics = 0;
if (GdipCreateFromHDC(ImgHDC, graphics) == 0) {
if (GdipDrawImageRectI(graphics, img, 0, 0, imgW, imgH) == 0) {
BITMAP bm; GetObject(hbmReturn, sizeof(bm), &bm);
BYTE* pBits = (BYTE*) bm.bmBits;
// Flip image to create reflection
GdipImageRotateFlip(img, 6);
// Add reflection to bottom of original image
GdipDrawImageRectI(graphics, img, 0, imgH, imgW, imgH);
long W = imgW, H = imgH;
long AlphaStep = 256;
long x, y, UseStep = 128 / (UseImgH - H);
BYTE Alpha;
for (y = 0; y < UseImgH - H; y++) {
for (x = 0; x < W; x++) {
Alpha = BYTE(max(pBits[3] - AlphaStep, 0));
pBits[3] = Alpha;
pBits += 4;
}
AlphaStep -= UseStep;
}
DWORD AlphaCoef;;
for (y = 0; y < H; y++) {
for (x = 0; x < W; x++) {
if (pBits[3] != 0) {
AlphaCoef = (255 << 8) / pBits[3];
pBits[2] = (BYTE)(((DWORD)pBits[2] * AlphaCoef) >> 8);
pBits[1] = (BYTE)(((DWORD)pBits[1] * AlphaCoef) >> 8);
pBits[0] = (BYTE)(((DWORD)pBits[0] * AlphaCoef) >> 8);
}
pBits += 4;
}
}
imgH = UseImgH;
nRet = hbmReturn;
}
// Cleanup
GdipDeleteGraphics(graphics);
}
GdipDisposeImage(img); img = 0;
DeleteDC(ImgHDC);
}
return nRet;
}
To both of you, thank you for your support !
-
Patrice--
You have a bug in GDImage64.dll in function ZD_GetTextBound()
invalid definition...
C_IMPORT long ZD_GetTextBound (IN WCHAR* sUseText, IN WCHAR* sUseFont, IN long UseSize, OUT long &TextWidth, OUT long TextHeight, IN long UseStrFormat)
should be OUT long &TextHeight
and ofcause need recompile GDImage64.dll...
this function not return TextHeight, therefore this code useless
// Darken text background to enhance readability while hover lighter background
long nbW = 0, nbH = 0;
ZD_GetTextBound(zCaption, (WCHAR*)$USEFONT, 6, nbW, nbH, ZD_TextHorzUp);
HDC hDCtxt = CreateCompatibleDC(DesktopDC);
HBITMAP hBmptxt = zCreateDIBSection(DesktopDC, nbW, nbH, 32);
SelectObject(hDCtxt, hBmptxt);
long nBackColor = ZD_ARGB(128, 255,255,0);
ZI_GradientPaintDC(hDCtxt, 2, 3, nbW - 4, 3, nBackColor, nBackColor);
zDrawTextToDC(hDCtxt, zCaption, 0, 0, ZD_ARGB(255,0,0,0), (WCHAR*)$USEFONT, 6, 0, ZD_TextHorzUp);
ZI_AlphaBlendEx(hDC, x , y - 2, bW + 1+10, bH + 4, hDCtxt, 0, 0, nbW, nbH, 200, 0, 2);
DeleteDC(hDCtxt);
DeleteObject(hBmptxt);
-
Andrey--
ZD_GetTextBound has been fixed, and both GDImage64.lib and GDImage64.dll have been updated into the latest candidate zip file attached to the first post of this thread.
In DrawDockBar, i have REM out the code following:
// Darken text background to enhance readability while hover lighter background
it has been replaced inside of DrawTextToDC, by the BlurTextPlus used into GDImage for my WinDev applications (Fly worship, ProBand, and BassBox Radio), this is also the same being used for text display inside of MediaBox when using ZD_DrawTextToCtrlEx.
Bluring text is great when using white text, even on a white background.
Andrey, is that your real name, because from your IP address you are leaving in Shenzhen, China ;)
Emil--
Try to REM out the code that has been added for standalone EXE, to see if it makes any difference.
Please, try also with the PowerBASIC version, and tell me if you have the same problem.
Thank you.
-
after debug i see that
if (FlagFound) {
if (EnableFlag) {
if (FileExist(sUseThumb)) // = @PATH@UserIcon\48x48\????.png
how why FileExist is true with no Icon ?
please check your FileExist function
it is because (?) is a wildcard character... means any char... while (*) means any sequence of chars
lpFileName [in]
The directory or path, and the file name, which can include wildcard characters, for example, an asterisk (*) or a question mark (?).
so if you get true it is mean that you have a file in that directory, which have name {4 any characters}.png (mask: "????.png")
for test if file exists better use
BOOL FileExist(LPCWSTR lpFileName)
{
DWORD dwAttr = GetFileAttributes(lpFileName);
return ((dwAttr != INVALID_FILE_ATTRIBUTES) && !(dwAttr & FILE_ATTRIBUTE_DIRECTORY));
}
-
Emil, Andrey,
I have just downloaded your two attachments, i will check them with my current work, and come back to you once done.
To both of you, thank you for your continuous support !
-
Emil
I have merged your code into mine, but i couldn't get it to work correctly with a custom OTB file (i see several RecycleBin).
Indeed RecycleBin, should not be moved around, and always kept at the first location, because it is a special case (not a real link), and that would kept the code simpler and smaller.
I shall take care of that within the new standalone version, and just ignore the recyclebin found in an existing OTB file.
Note: my new standalone release version does use vector, probably the reason why my code is 30 Kb larger than Andrey's.
-
I found also that my cleanup code needs to be reworked.
I must add an array.delete function and shift the array accordingly, just like in the original PB's version.
Perhaps i should switch everything to vector ;)
-
Pure C project (PellesC project)
size of executable
32bit - 86Kb
64bit - 105Kb
-
Andrey
I had the opportunity to quickly check your
OfTheBayUnisRev.rar
Seems to work very well :)
However, as Emil wrote, this type of coding style breaks the compatibility with the PB's version that cost me much efforts to preserve ???
I shall probably try to find a good balance between compatibility, and your great submission 8)
(by the way i still have much to learn about advanced C programming, i started to really program in C++ when it becomes obvious {to me} that there will be never a 64-bit PowerBASIC version).
-
Andrey
Thank you for deleting the gP.img[] at the end of WinMain,
this is what was done in the original code inside of zsRemoveAllImageResource during WM_DESTROY (zsDisposeImage)
I totaly forgot about that one ;)
Added:
length, rect, and many more are reserved words in PowerBASIC that is not a case sensitive language, this is the reason why i avoid to use them in C++, because i am always porting code from one language to another, that would help me if you keep this in mind for future contributions ;)
For example HBITMAP hBitmap is a NoNo for me 8)
More:
Did i say that i really appreciate your deep knowledge of the core low level SKD API, by today's standard that is getting very rare :D
And the more i look at your code, the more i think that you should have spent much time with all my different code submissions.
-
My version... (a small update)
32bit - 117Kb
64bit - 130Kb
doesn't create temporary files... convert images direct...
number of sprites limited by available memory only...
static linked gdiplus...
more optimized code...
...
save ini file in right place
small fixes
RecicleBin will be always first
Added
What for need ResolveLnk()? I didn't see any *.lnk files in text format...
-
What for need ResolveLnk()? I didn't see any *.lnk files in text format...
I wrote the original code long ago, and i can't rember for sure, however i think to remember that it is related for this specific case
You can create a shortcut to a Control Panel tool by dragging an icon from Control Panel to the desktop or another location,
or by manually creating a shortcut and specifying the path to a .cpl file.
Same for FILE_EXT zExt[3] = { L".cpl", L".exe", L".dll"};
https://support.microsoft.com/en-us/help/149648/description-of-control-panel-.cpl-files
I keep working on the new release, tyring to mix your changes with mine altogether.
-
Andrey,
I get these errors with your PellesC project as a 64bit app on
Windows 10:
Version 1703
OS Build 15063.296
As a side note I am also getting resource file errors compiling PBWin10 apps with this Windows 10 build.
James
Building OfTheBay.exe.
POLINK: error: Unresolved external symbol 'EncoderQuality'.
POLINK: error: Unresolved external symbol 'FOLDERID_Desktop'.
POLINK: error: Unresolved external symbol 'IID_IPersistFile'.
POLINK: error: Unresolved external symbol 'IID_IShellLinkW'.
POLINK: error: Unresolved external symbol 'CLSID_ShellLink'.
POLINK: error: Unresolved external symbol 'FOLDERID_PublicDesktop'.
POLINK: fatal error: 6 unresolved external(s).
*** Error code: 1 ***
Done.
-
Andrey,
I get these errors with your PellesC project as a 64bit app on
I've used this SDK _http://forum.pellesc.de/index.php?topic=7017.0
That cause the problem...
attached updated version... should be compiled now
Added:
By the way Andrey, there are some part of the code when reading images that i didn't remember to have ever posted here (especially magenta processing and the alpha channel change for mouse detection). :)
You post somewhere... I don't remember where from, but I have CRD3.zip -> gControl.inc
And I can recover source code from compiled binary... (made functional analog...)
Many years of Reverse Engineering... ;)
-
A new standalone version of 139 Kb has been attached to the first post of this thread.
More code cleanup and further mix with Andrey's...
So far, i plan to post both projects in the official release, and i could also post Emil's Delphi version if there is a final one.
Andrey, have you ever worked with OpenGL?
...
-
All contributions have been attached into the "Eye Candies" section.
-
Of The Bay 3.00, has been posted to codeproject, altogether with Andrey's and Emil's version,
here : https://www.codeproject.com/Articles/1194952/Of-The-Bay-dock-bar
-
Here is the message that has been sent to me, to explain why 8)
Hi zapsolution,
Thanks very much for your contribution to CodeProject. However, your article 'Of The Bay (dock bar)' in the Desktop Gadgets section at
https://www.codeproject.com/Articles/1194952/Of-The-Bay-dock-bar
has been deleted. Would you be willing to make some changes to your article? Unfortunately this is more akin to tool sharing, which is something we do not do on CodeProject. CodeProject is more about code teaching.
CodeProject articles have a certain layout to follow, so that users can learn the most from them. Each article attempts to answer the following questions: What problem does this solution solve? How does this help someone else? How does the code actually work? What is going on inside the code snippets?
Here is a submission from a first time author who did a terrific job, just to give you a basic overview of what a beginner article might looks like: http://www.codeproject.com/Articles/37642/Avoiding-InvokeRequired
You can take a look at our article FAQ here: https://www.codeproject.com/Articles/64119/Code-Project-Article-FAQ
For tips on writing articles, please see this article: https://www.codeproject.com/Articles/3360/A-Guide-To-Writing-Articles-For-Code-Project
You can also see our submission guidelines here: http://www.codeproject.com/info/submit.aspx
Please let me know if you have further questions.
Regards,
Sean Ewington
-
Oh yeah,
"There ain't no such a thing as a free lunch" (U.S. Eng.)
"Cheese comes free only in a mouse trap" (Russ.)
:-\