SetSystemCursor replaces the system cursor specified by the second argument ( OCR_CROSS in this example) with the cursor in the first argument. So, you set the OCR_CROSS cursor first to Normal, then to IBeam, so in fact the cross-cursor will look like IBeam.
The documentation also states that
The system destroys hcur [first argument] by calling the DestroyCursor function. Therefore, hcur cannot be a cursor loaded using the LoadCursor function. To specify a cursor loaded from a resource, copy the cursor using the CopyCursor function, then transfer the copy to SetSystemCursor.
Your code does this, so things may go wrong, or at least with leak handles.
In-depth appearance
SetSystemCursor much more invasive than you think. In fact, it swaps the global cursor data of the specified cursor in the second argument with the cursor object in the first argument.
This has consequences. Let's say that you replaced IDC_WAIT with IDC_CROSS , and then IDC_ARROW with IDC_WAIT (C code):
HCURSOR hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_CROSS)); HCURSOR hCopyCursor = CopyCursor(hCursor); SetSystemCursor(hCopyCursor, (DWORD)IDC_WAIT); // Replace Wait by Cross HCURSOR hCursor2 = LoadCursor(0, MAKEINTRESOURCE(IDC_WAIT)); // Load whatever is in Wait and put it in Arrow HCURSOR hCopyCursor2 = CopyCursor(hCursor2); SetSystemCursor(hCopyCursor2, (DWORD)IDC_ARROW); // Replace Arrow by Wait.
Question: Is the cursor on the system cursor the "Cross" or "Wait" cursor?
Answer: This is a cross cursor.
The reason for this is because you are actually changing the underlying cursor data, not just a link, so LoadCursor reads the replaced cursor data.
It also shows why this gets very confusing when you don't make a copy of the cursor at the beginning: then two cursors get exchanged globally.