Showing posts with label Coding. Show all posts
Showing posts with label Coding. Show all posts

Friday, August 26, 2016

ITaskbarList3 interface using plain Windows API

The ITaskbarList3 interface can be used by application (from Windows 7 onwards) to perform following actions:
  • Showing the progress of an operation in the taskbar
  • Showing an overlay icon over the taskbar item
  • Add a tooltip to the taskbar thumbnai
  • Adding a toolbar to the taskbar of the application
Even the interface functions are descibed at MSDN (see link below), getting it to work might not be that easy. Therefore here are the steps to make use of the ITaskbarList3 from a C/C++ application using plain Windows API:
  1. Include Shobjidl.h
  2. Initialize the COM library by calling CoInitialize() or CoInitializeEx()
  3. After your main window is created (e.g. after CreateWindowEx() call), define the message "TaskbarButtonCreated" using RegisterWindowMessage():
    UINT taskbarButtonCreatedMessageId = RegisterWindowMessage ( "TaskbarButtonCreated" );
    Store the returned message ID for later use.
  4. To ensure that your main window receives this message, enhance the message reception filter privileges:
    ChangeWindowMessageFilterEx(mainWindow, taskbarButtonCreatedMessageId, MSGFLT_ALLOW, NULL);
  5. Afterwards the message with ID returned by RegisterWindowMessage() is sent to the window procedure of your main window. If it's received, create an instance of the ITaskbarList3 interface using CoCreateInstance():
    ITaskbarList3* pTaskbar = NULL;
    LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
      if (uMsg == taskbarButtonCreatedMessageId)
      {
        HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, reinterpret_cast(&pTaskbar));
      }
    ...
    }
  6. From now on, you can call the ITaskbarList3 functions using variable pTaskbar, e.g. pTaskbar->SetProgressState(hwnd, TBPF_ERROR);
  7. Before quitting the application, remember to release the interface and close the COM library:
    pTaskbar->Release();
    CoUninitialize();
I hope those steps help you in order to use this interface. For an working example with source code, see http://sunshine2k.de/c.html#windowsprogressbar.

ITaskbarList3 interface at MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/dd391692(v=vs.85).aspx

Regards, Sunshine2k

Tuesday, August 12, 2014

Where does 116444736000000000 come from?

While dealing with time conversions functions of various languages / technologies, e.g. Windows API or Java, you might come across the magic constant 116444736000000000. You can also find it in several code snippets on the web - however it never nearly explained where it comes from... This I wanna change, here and now!

A time value is simply a counter of ticks since an defined start of time, called epoch. Not only the "epoch date" differs between various systems, but also the counter resolution, that is how often it is updated.

Windows uses in most functions the FILETIME structure, which represents the actual time as the number of 100-nanosecond intervals since January 1, 1601 (UTC).

Other platforms like Java/Android or some Unix functions represent a time value as the number of seconds elapsed since 00:00:00 January 1, 1970.

To convert between both worlds, you need an offset factor and that is... 116444736000000000. This value used as a FILETIME value, meaning 100ns intervals since 01-01-1601, represents exactly the data 01-01-1970!

Proof?
We know that 1ms = 1000000 ns = 10000 * 100 ns.
So 116444736000000000*1/100 ns = 11644473600000 ms = 11644473600 s.
Between 01-01-1601 and 01-01-1970, there are exactly 134774 days.
134774 * 24 (hours per day) * 3600 (seconds per hour) = 11644473600 s.

Thursday, November 15, 2012

My alternative to HTML frames

Maybe some of you have noticed that I have updated my homepage. Well, the content remained more or less the same but the layout was finetuned.
Furthermore, the previous pages were created using a WYSIWYG tool which resulted in pretty ugly, overbloated HTML. Of course it was also hard to maintain and lacked of HTML validity.

The new pages were manually written (hm okay.. copy-pasted). The biggest difference is the fact that they are not frame-based anymore but solely CSS-based (I avoided to use tables for solely layout purposes as much as I could).
But when searching the net for alternatives to frames, my plan turned out to be more difficult than expected. Using I-Frames was no choice. PHP is not supported by my webspace and I was not willing to pay more just for some 'include' directives.
On the other hand, each change of the main layout (header at the top, meu at the left border) would have meant to manually adapt each html file... this is unacceptable.

So what to do?
Actually I came out with my own solution:
1. I started by coding a main layout template file which contains the general layout without any content:



2. This template was then used as base for every html page of my site. Well, so far no advantage. But in each file I put some markers to identify which parts of the html source belongs to the template and which parts contain the actual new content. These markers are just pre-defined HTML comments like:


here comes may cool individual HTML content



3. Then I programmed a fancy tool which compares all files belonging to my site to the latest template. The markers help to identify the regions which belong to the template file and which are individual content. When the template changes, my tool can update the page files in a way that only the template regions are updated but the actual content is not touched. Here a screenshot of my tool:


A single button click will then update all sites :-)

What do you think of this solution?
Well, I must admit it took some time to code it and get it correctly working, but it was fun to write it and it works like a charm.
.. I love my own-invented solution!

Saturday, December 03, 2011

Reason for homogeneous (4D) coordinates in computer graphics

Homogeneous coordinates are used computer graphics - you can read this statement in every 3D computer graphics related book or article. If you ever asked yourself why this is the case, then you are at the right place...
The reason for this is to handle rotation, scaling and translation in a common way. While you can handle rotation and scaling using 3x3 matrices and vectors with 3 components, translation cannot be processed - unfortunately this is normally not further explained although it is quite easy to see:
Suppose we have a point p with coordinate (x, y, z) and we want to translate it by a distance defined by the translation vector t=(tx, ty, tz).
Of course, what you need to do to get new position p' of point p after translation is to add t to p:
p' = p + t, which means
p'.x = p.x + tx
p'.y = p.y + ty
p'.z = p.z + tz
If you try to create a 3x3 matrix M to perform this operation by p' = M * p, you get into trouble. What we require is:

x'   x + tx   |a b c|   |x|
y' = y + ty = |d e f| * |y|
z'   z + tz   |g h i|   |z|

x + tx = ax + by + cz (1)
y + ty = dx + ey + fz
z + tz = gx + hy + iz

Looking at equation (1) we directly see that a = 1 and we are left with tx = by + cz. But the translation in x-direction must be indepent of y and z coordinates, so b and c must be zero.

x + tx = 1*x + 0*y + c*z = x   => tx = 0
So only the primitive translation by zero is possible. The same applies for the equations for y and z.

Using homogeneous coordinates, that is to add a forth component w = 1 to each point, we can derive a 4x4 matrix for translation without any problems.


x + tx   |a b c d|   |x|
y + ty = |e f g h| * |y|
z + tz   |i j k l|   |z|
1        |m n o p|   |1|

we get e.g. for x-coordinate:

x + tx = ax + by + cz + d, 
so a = 1 and d = tx which leads us to the final translation matrix:

    |1 0 0 tx|
M = |0 1 0 ty|
    |0 0 1 tz|
    |0 0 0 1 |

That's it :-)




Saturday, August 01, 2009

Am I a stupid user?

Sometimes I wonder if I am to stupid to use some tools or if the GUI is not like that as it should be. I am using Visual Studio 2005 now for several years and some weeks ago I tried to change the height of the client area of a normal combobox inside resourse editor. The reason was that I added around 20 text items from code and wanted them to be visible all at the same time in the dropdown list. Well in the Properties Window there is no such attribute to set and when I clicked the combobox it looks like this:

But it was only possible to change the width of the combox (blue spots) and not the height (white spots)! I just thought "Oh man what's going on... this cannot be true - I am going nuts!".
My first idea was to change the height from source code using MoveWindow etc. - but in total this required more than 5 lines of code (with variable declaration and nice layout) just to change the height of a dropdown list of a combobox...?! This is not that developer-friendly as I expected it...

Or was I just too stupid to use resourse editor - of course this was the case. But I found the solution only accidently. Instead of clicking directly on the combobox item, I clicked directly on the small button with the arrow downwards at the right side of the textbox, and suddenly it looked like that:

Now it was possible... that easy!
Although I feel some kind ashamed to waste so much time for such a trivial problem, I thought posting my lousy problem may help also some other 'stupid user' facing the same 'challenge' ;-)

Thursday, October 30, 2008

Accessing Webcam & pre-process frame

One evening I asked myself how to access my laptop webcam (a noname 1.3MP cam integrated into my HP Pavillon dv6XXX) by code. As I faced a little problem with this, I want to share my experience with you.

A look at msdn/internet revealed the Windows Capture Functions, all starting with the prefix cap. Creating the capture window, connecting to the driver, scaling, enabling preview - all very easy as these are just simple function calls. Cause I wanted to preprocess the frame (in order to implement some algorithms to make nice effects - which is not done yet and will take some more time...) I engaged a frame callback function without problem.

But then a little obstacle occured: how is the frame data stored? Using capGetVideoFormat, I accessed the bitmapinfoheader structure and checked the biBitCount member - 16 Bits. Ok - nice - and started coding immediuately which turned out to be a mistake!
The color members were not stored as specified in the msdn library: least significant five bits blue, followed by five bits each for green and red and the most significant bit is unused.

At first I thought I introduced a bug on my bit operations to extract these bits - but no, works perfectly.

Ok, no big deal - as I wished the data to be 24bit RGB, I wanted to use capSetVideoFormat to change the captued video data to this format. But of course this solution would have been too easy - this function always returned FALSE meaning my webcam driver does not like another format :-(

So what was the problem?
While tracing the program I saw the bitmapheader structure values in the debugging window inside visual studio and the biCompression member caught my eyes: 844715353. Hm such a value is not predefined as e.g. BI_RGB etc. I converted this number to hex = 0x32595559 and searched the internet to find out that this is the fourcc of YUY2! Another search brought my to the great website FourCC.org where this format (and many others) is explained:
a simple 4:2:2 YUV format with byte order Y1 U Y2 V. With this info it's of course easy to preprocess each frame of my webcam as I want.
Of course a better BitmapInfoHeader Page at msdn would have saved me a lot of time... Although interestingly a few days later I found this page at msdn where I found exactly my required information - but just too late.

I hope this will help someone facing the same problem while accessing a webcam!

Wednesday, September 17, 2008

A bug hard to find...

During the last evenings, I have been coding a little tool to convert Avi files to 4:2:0 Yuv files. I just wanted it to have more videos to test with my H.264 encoder I work with in my diploma thesis. Well, it was no big deal programming it, just diving into the Video for Windows Api on MSDN to get familar with its interface so it didn't take long till I finished it. It's a console application and I always tested inside Visual Studio, passing the commandline parameters in the project settings. So everything worked fine till I tested it inside a cmd window outside Visual Studio. The converting loop was successful but it freezed after printing "Done!". Looking at the code I was surprised cause that printf("Done!\n") is the very last command!
That's the pseudocode:

for all frames
   pData = (BYTE*)AVIStreamGetFrame(pFrame, i-1);
   CreateYuvfromFrame(pData);
CloseAviFunctions();
printf("Done\n");
return;

Inside Visual Studio, I found at first no hint what was wrong, even tracing it showed no problem. Than I noticed that it does not freeze when the for-loop is not entered. Again reading in msdn, more specific AviStreamGetFrame, I read following:

Remarks:

The returned frame is valid only until the next call to this function or the AVIStreamGetFrameClose function.

Then I suddenly noticed, I called every necessary Avi-release and Avi-close function except the AviStreamGetFrameClose one. Inserting it just before my program ends and the bug was gone... and I was happy!

So what we learn from this: when using the Video for Windows Api, make sure to call the corresponding close-function for every Avifunction you use, although MSDN does not explicitly state that you have to before your program finishes!

But the open question remains: how to find this bug in a structured straightforward way? Normal debugging did not help and I was not willing the spend all my time to debug internal system calls within Ollydbg.
So if you know a way or you have just a suggestion, feel free to tell it me!


Thursday, March 06, 2008

Maximum subvector problem

So folks,
again a life sign from me. Again I'm busy... Currently I'm writing the paper of my study thesis. This needs more time than I thought but fortunately my monitoring unit works on the fpga. On the side I started to learn for my last oral exam - in computer graphics. That means hard-core diving into bézier and b-spline curves, also in point clouds. That's gonna be difficult and time-consuming.
Nevertheless while surfing, I came across a paper about the so-called maximum subvector problem. I even think that I really had this problem some years ago while coding. Although it's quite simple it's somehow cool to think about solving it. So what it is about?

given : an array[1...n] of (positive and negativ) numeric values
goal: to determine the maximum subvector a[i..j], 1 <= i <= j <= n whose sum of elements is maximum over all subvectors. Well, not that big thing at first - just calculate all possible subvectors and save the maximum one. The straightforward approach could be look like this: MaxSoFar := 0.0
for L := 1 to N do

  for U := L to N do

    Sum := 0.0

    for I := L to U do

      Sum : = Sum + X[I]
      /* Sum now contains the sum of X[L..U] */

      MaxSoFar := max(MaxSoFar, Sum)


This works of course but for even quite small array sizes (e.g. 1000 elements) this lasts quite long. The execution time is proportional to O(n^3)!
This just be motivation enough to search for some better algorithm. Well, after some thinking you might find a O(n^2) algorithm. There is even a divide-and-conquer approach which is in O(nlogn), but it's not that easy to code :-( Ok, nice, they are often hard to implement...
But in fact there is a simple algorithm that works in linear time! Yes, in O(n)! I must admit I had never expected it nor searched for it. And it is so simple!!!
Curious? Ok here it is:

MaxSoFar := 0.0
MaxEndingHere := 0.0
for I := 1 to N do
  MaxEndingHere := max(MaxEndingHere+X[I], 0.0)
  MaxSoFar := max(MaxSoFar, MaxEndingHere)

So if you found this blog entry interesting, then be sure to check out following article, it contains everything I've written here:


Bye

Friday, October 26, 2007

My hook doesn't work :-(

A few days ago I rummaged through my old code snippets and sources on my harddisk. I noticed that I coded quite many PE tools, especially with Delphi, but something I have never created - an Api hook!
I read pretty much about it (there are many code snippets in the net about this), but most of them are complicated and badly commented so that it's difficult to undertstand what's going on. So I tried myself and began coding the most simple and clean api hook possible (in c cause it's better to read than asm): a little Messagebox hook which should alter the caption of all messageboxes.
Ok I thought, the most simple approach is to code a loader which starts a target process and loads my selfcoded 'hook dll file' into the address space with the well-known CreateRemoteThread trick. Inside the dll file is all the work: as soon as injected and attached, it travels through the import table of the process, searches for MessageBoxA API from user32.dll and replaces the RVA (called Thunk) with the RVA of my own function I declared in my dll file. Hm... sounds not bad although I know that this works just with exes with a straightforward import table - even loading the MessageBox API with GetProcAddress would bypass my approach. But that's not bad - if it would work.... Damn!
With some targets it works, but in others it corrups the stack!? That's a bit strange to me - either it should work always or never. Of course, I took special care about the arguments and the stack. And debugging with olly is quite boring and not that easy... I think I give up and I put up with the fact that I'm never gonna code a nice Api hook :-(

Moreover, studies suck also -> 'thank god it's friday' and I will relax the whole weekend!

Wednesday, February 14, 2007

Working at my Brainfuck Studio

So, today I had some time, so I continued coding my Brainfuck interpreter in c#.
Well, most basic things work: step-by-step, run-to-cursor and normal execution work fine. Also do saving/loading files, syntax highlighting, a comment feature and much more do what they should... But also a lot of minor bugs impede working with it. And when I look at some parts of the source code, my eyes bleed... too ugly, but it gets better :-)

Also I have really many ideas I want to implement, so it will last a couple of weeks till I'm going to publish a beta version on my site.

But here a screenshot of its current state:

Thursday, July 20, 2006

Nice Article

Hi,

well I spent most time outside in the sun, so only few time for computer. But I came across a nice article about some pitfalls in c++... just wanna give it to you. Worth reading for beginner/intermediate c++ coders... Enjoy it
-> Click here

C ya

Monday, May 22, 2006

Fancy code for swapping integers

Good evening.

While surfing the internet, I just came across some articles about bitwise operations in C. There I found a fancy code snippet for swapping two 'ints'. Well I never thought about it but if I had to code a little swapping procedure, it would probably something like this:

void swap(int* x, int* y)
{
int z = *x;
*x = *y;
*y = z;
}


Ok, quite easy. Just use a temporary variable... but there is another approach without a third variable, just look at this:

x ^= y;
y ^= x;
x ^= y;

Really cool xor-action, isn't it? Try to figure out what's going on here. (Tip: x ^ x = 0)
Well, every day I learn something new... but that's enough for now.
Good night. :-)