I'm trying to fetch the cursor bitmap in order to compute a snapshot with the mouse cursor.
It works fine with the standard cursor (IE. the arrow) but it fails as soon as the cursor becomes a text cursor.
Basically I'm doing this :
//Fetching the cursor handle
GetCursorInfo( &m_infos );
m_handle = m.infos.hCursor;
//Fetching cursor info
ICONINFO infos;
HICON icon = CopyCursor( m_handle );
GetIconInfo( icon, &infos );
BITMAP bitInfos;
if ( GetObject( infos.hbmColor, sizeof( bitInfos ), &bitInfos ) == 0 )
{
qDebug() << "Error N:" << GetLastError();
}
The problem is, GetObject() AND GetLastError() return 0... so i'm not abble to know which is the error...
I'm running this code on Win7, using QtCreator and MingW.
Any idea, clue, would be much appreciated !!
Thanks a lot in advance !
There is no "text cursor". It's called a caret, and it's dealt with totally differently than the mouse pointer. See Using Carets on MSDN for more info.
infos.hbmColor is probably NULL. MSDN says for ICONINFO.hbmColor:
A handle to the icon color bitmap. This member can be optional if this structure defines a black and white icon.
Usually, the text cursor (IDC_IBEAM) is defined by using only color inversion and transparency, explaining the fact that hbmColor is NULL. You should always apply hbmMask to the optional hbmColor.
Related
I have a Tizen Edje file which defines my layout. One part is an image with part name 'warning'. The item is set to visible in the edge file, and it shows as expected.
I want to hide this part using C code:
Evas_Object* image_NotSetYet = (Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(wid->edjeLayout), "warning");
if (image_NotSetYet == NULL) {
dlog_print(DLOG_ERROR, LOG_TAG, "View: Unable to get warning image part");
return;
}
evas_object_hide(image_NotSetYet);
I have tried many different ways to get the Evas Object associated with this part name and hide it. After many hours I stumbled onto some code that I modeled after, and it seems to work. I can hide (and show) my image part now.
However, I later add an unrealted image to a swallow in this layout and show it. All of a suddent the 'warning' part image shows again. Why? Am I hiding the 'warning' part the wrong way? Is there something wrong with the above?
Alternatively, is there something wrong with the way I am adding an image to the swallow below? The image (from file) will show up, but suddenly my warning part above shows too:
Evas_Object *img = elm_image_add(wid->edjeLayout);
if (img == NULL) {
dlog_print(DLOG_ERROR, LOG_TAG, "View: Failed to add a image.");
return;
}
// Create an image and set contents to imagefile
char *imageFileName = barcode_filename();
bool isSet = elm_image_file_set(img, imageFileName, NULL);
dlog_print((isSet?DLOG_INFO:DLOG_ERROR), LOG_TAG, "View: %s file [%s] to image",(isSet==EINA_TRUE?"Set":"Failed to set"),imageFileName);
free(imageFileName);
evas_object_show(img);
// Assign the image to the swallow2 part
elm_object_part_content_set(wid->edjeLayout,"swallow2",img);
I tried adding the image to the 'window' instead of the 'layout' but that didn't seem to matter. (I've seen many contradictory examples so I don't know which is right)
I tried setting the image to the 'swallow2' part name many different ways (again, many contradictory ways show). Is this the problem?
Otherwise, can someone explain what is going wrong?
The image_NotSetYet is not an image object.
Evas_Object* image_NotSetYet = (Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(wid->edjeLayout), "warning");
That refers to the "warning" swallow part object.
You should never modify the state of the returned object, because it's meant to be managed by Edje, solely.
If you want to get the image pointer from your layout as you expected, you could use following instead.
Evas_Object* image_NotSetYet = elm_object_part_content_get((wid->edjeLayout), "warning")
But as above link describes, the image object should be manged by Edje.
You might got the 2nd problem because it is managed by Edje. So please use edje_object_signal_emit to handle swallowed images.
My situation is like this. I wrote a code that checked a group of windows if their content are eligible to be swapped or not (that is all the redrawing are successfully performed on the said window and all its children after a re-sizing event). Should the conditions be met, I performed glXSwapBuffers call for the said window, and all its children. My aim was to allow for a flicker-freed-upon-resizing system. The child windows were arranged in tile fashion, and does not overlap. Between them, the function appeared to work. My issue however, arise with the parent. Sometime during the re-sizing, its content flickers. So far, this is what I have implemented.
All the events such as ConfigureNotify, or Expose, are already compressed as is needed.
The window background_pixmap is set as None.
Understanding that whenever an Expose event is generated, window background content is lost. With every redrawing done, I keep always keep the copy of the finished redraw in my own allocated buffer. (Neither a pixmap or fbo, but it suffices for now.)
My logic for each call to glXSwapBuffers() is this.
void window_swap( Window *win ) {
Window *child;
if ( win ) {
for ( child=win->child; child; child=child->next )
window_swap( child );
if ( isValidForSwap( win ) ) {
glXMakeCurrent( dpy, win->drawable, win->ctx );
glDrawBuffer( GL_BACK );
RedrawWindowFromBuffer( win, win->backing_store );
glXSwapBuffers( dpy, win->drawable );
}
}
}
Which...should serve, the content is always restored before a call to swap. Sadly, it did not appear so in the implementation. From the above code, I make some adjustment for the purpose of debugging by outputting what should be in the buffer as following.
void window_swap( Window *win ) {
if ( win ) {
if ( isValidForSwap( win ) ) {
glXMakeCurrent( dpy, win->drawable, win->ctx );
glDrawBuffer( GL_BACK );
OutputWindowBuffer( "back.jpg", GL_BACK );
RedrawWindowFromBuffer( win, win->backing_store );
glXSwapBuffers( dpy, win->drawable );
glDrawBuffer( GL_BACK );
glClearColor( 1.0, 1.0, 1.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
OutputWindowBuffer( "front_after.jpg", GL_FRONT );
OutputWindowBuffer( "back_after.jpg", GL_BACK );
}
}
}
The function OutputWindowBuffer() use standard glReadPixel() to read the buffer content and then output it as image. Which buffer is to be read is determined by the parameter passed into the function. What I've found out with the output picture is this.
The picture output of the back buffer after RedrawWindowFromBuffer() is what was expected.
The picture output of the back buffer after the swap is filled with the cleared colour as was expected. Thus, it is not the case that glReadPixel might be lagging in its execution when it was called for the Front buffer as some discovered bug about intel system seemed to suggest once.
The picture output of the front buffer after the swap show mostly black artifacts (My window's colour is always cleared to other colour before each drawings).
Is there other plausible explanations as to why swapping the buffer, does not appear to swap the buffer? Is there other routes I should be looking into as to implement a flicker-free re-sizing? I have read an article suggesting the use of WinGravity, but I'm afraid I don't quite comprehend it yet.
If your windows have a background pixmap set, then at every resizing step they get filled with that, before the actual OpenGL redraw commences. This is one source of flicker. The other problem is glXSwapBuffers not being synched to the vertical retrace. You can set this using glXSwapInterval.
So the two things to do for flicker free resizing: Set a nil background pixmap and enable glXSwapBuffers synched to vertical retrace (swap interval 1).
You can set the autocapitalizationType property of a UITextField so all input is in upper case. I find that does work fine on the simulator (when actually tapping the simulator's keypad, not the Mac's keyboard), but not on the device? Everything stays lowercase.
In the UICatalog demo I added to the textFieldNormal method:
textFieldNormal.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
Added a delegate too, to display the actual autocapitalizationType for the UITextField:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
NSLog( #"textField.autocapitalizationType=%d", textField.autocapitalizationType );
}
It will properly display 3 (=UITextAutocapitalizationTypeAllCharacters), but anything you tap remains lowercase. What am I missing?
Apparently this is a device general settings issue: Settings -> General -> Keyboard -> Auto-Capitalization must be ON to honour the setting of textField.autocapitalizationType to all upper case, else setting the property is ignored, apparently. If I switch it on everything works as expected.
You could try something like this the the textfield delegate:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (range.length == 0) { // not deleting , but adding a char
textField.text = [textField.text stringByAppendingString:[string uppercaseString]];
return NO;
}
return YES;
}
This works only if you try to insert a symbol at the end of the text.
Should you want to play with the text in the middle you could play with
range.location
and also you will need to play with the cursor positioning as it will go at the end every time...
I hope this helps someone.
I attempted the following in a call to XCreateWindow():
unsigned long ctt_attribute_mask = CWWinGravity | CWCursor;
ctt_attributes->win_gravity = NorthEastGravity;
ctt_attributes->cursor = XC_arrow;
ctt_window = XCreateWindow(dpy, parent, ctt_xpos, ctt_ypos,
ctt_xy_size, ctt_xy_size, ctt_border,
ctt_depth, ctt_class, ctt_visual,
ctt_attribute_mask, ctt_attributes);
This creates the window, but it doesn't affect the pointer when it rolls over the window.
I want to use the user's desktop environment's standard pointer cursor when the mouse appears over my window.
Xlib is required, because this is a toolkit-agnostic program.
ETA: Additional context is available; see create_ctt_window starting on line 35 in the source file.
ctt_attributes->cursor = XCreateFontCursor(dpy, XC_arrow);
This is not the desktop environment's standard pointer cursor, this is the X11 rather ugly bitmapped cursor. If you want themed cursors, use libXcursor. I have no experience with it.
Here's the example from The Xlib Programming Manual, vol 1, p 182.
#include <X11/cursorfont.h>
int cursor_shape = XC_arrow;
Window window;
Cursor cursor;
cursor = XCreateFontCursor(display, cursor_shape);
XDefineCursor(display, window, cursor);
/* Now cursor will appear when pointer is in window */
So it looks like n.m. is spot-on. You need to call XCreateFontCursor to translate XC_arrow (which is just an integer that designates the cursor's location in the font's encoding vector) into a Cursor resource. I think the Cursor resource is just an integer, too. That's why you get no compile error. But you do indeed have a type mismatch.
First of all, please bear in mind that I'm new to Windows Programming. I'll try to cover my question in great detail, so that hopefully the answer will be too.
A short introduction:
I'm copying writing a Notepad-like application using Win32 API and pure C. For those of you familiar with Petzold's Windows Programming, this is a modified version of his POPPAD program which he used to describe Common Dialog Boxes. I'm writing this strictly for educational purposes, so please refrain from posting comments like "why you using old technology, use .NET", as those comments will not help me solve my problem :).
Description of a problem:
Petzold in his POPPAD program used Common Dialog Boxes to write this Notepad-like application. He used Edit Control to provide all the functions of a basic text editor. POPPAD, much like a Notepad, also had Find and Replace dialog boxes where you could, well, find stuff AND replace it! Mind boggling, I know.
So this is where I wanted to test my newly acquired knowledge from reading the past chapters, as I decided to write my very own Find and Replace dialog box. Granted, it would be in the simplest form possibly. How hard can it be? You have one text field where you enter some text and you have one fancy button which says "Find!" on it.
Now I'd like to remind you once more that I'm new to Windows programming, so excuse me for any possibly newbie questions. Also, I'd like to point out that I'll focus solely on making the Find dialog box working, as Replace shouldn't be too hard to implement then.
So I played with the resource editor in Visual Studio, and few hours later I got this:
(stackoverflow doesn't actually allows me to post images, so here's the link below)
http://i.imgur.com/R98x4.png
I named this dialog box "Find" (with the quotation marks), so I don't have to use MAKEINTRESOURCE macro in my program, as per Petzold's school of thought. I changed the caption of "Ok" button to "Find Next" and changed it's ID from IDOK to IDC_FIND. Also changed IDCANCEL to IDC_CANCEL and that single line Edit Control is IDC_FIND_FIND.
Now to the more serious things. In my main program's Windows Procedure, I have this piece of code:
case IDM_SEARCH_FIND:
hDlgModeless = CreateDialog (hInst, TEXT ("Find"),
hwnd, FindDlgProc) ;
return 0 ;
IDM_SEARCH_FIND is a message identifier of a Menu item, which when clicked should open up the Find dialog box. CreateDialog function is used to create a modeless dialog box and store it's handle into a global variable hDlgModeless. FindDlgProc is name of the dialog box procedure where (I think) all the code of finding the text should go.
So without further ado, here's the code of my Find dialog box procedure:
BOOL CALLBACK FindDlgProc (HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
static TCHAR szFindWhat[MAX_STRING_LEN]; //Text to find
static int iOffset ; //Offset from the beginning of Edit control to the result
int iLength, iPos, iSingleLength ; //Length of a main Edit control and single line Edit control
PTSTR pstrDoc, pstrPos ;
switch (message)
{
case WM_INITDIALOG:
return TRUE ;
case WM_COMMAND:
switch (LOWORD (wParam))
{
//If the button "Find Next" has been pressed, process all the logic of finding the text
case IDC_FIND:
// Get the text from a single-line edit control in Find dialog box
// and save it in szFindWhat variable
iSingleLength = GetWindowTextLength(GetDlgItem(hDlg, IDE_FIND_FIND)) ;
GetWindowText(GetDlgItem(hDlg, IDE_FIND_FIND), szFindWhat, iSingleLength) ;
// Get the text from a main Edit control, allocate memory for it
// and store it in pstrDoc variable
iLength = GetWindowTextLength (hwndEdit) ;
if (NULL == (pstrDoc = (PTSTR) malloc ((iLength + 1) * sizeof (TCHAR))))
return FALSE ;
GetWindowText (hwndEdit, pstrDoc, iLength + 1) ;
// Search the document for the find string
pstrPos = _tcsstr (pstrDoc + iOffset, szFindWhat) ;
free (pstrDoc) ;
// Return an error code if the string cannot be found
if (pstrPos == NULL)
return FALSE ;
// Find the position in the document and the new start offset
iPos = pstrPos - pstrDoc ;
iOffset = iPos + lstrlen (szFindWhat) ;
// Select the found text
SendMessage (hwndEdit, EM_SETSEL, iPos, iOffset) ;
SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0) ;
case IDC_CANCEL:
DestroyWindow (hDlg) ;
hDlgModeless = NULL ;
break ;
}
break ;
case WM_CLOSE:
DestroyWindow (hDlg) ;
hDlgModeless = NULL ;
break ;
default:
return FALSE;
}
return FALSE ;
}
The only actual error I get here is that hwndEdit is undeclared identifier. hwndEdit is the main Edit control (not the single-line in Find dialog box). How do I get the handle to hwndEdit while I'm in a Find dialog box procedure?
I'd like to point out that I'm feeling a bit over my head here, so please say if I'm missing/doing wrong something obvious. I'm pretty sure that even if I fix the only error I'm getting, the program still won't work. Even though the concept of what I should be doing sounds fairly simple, actually programming that seems quite difficult :)
This is what the code above should do, in simplest form:
- Get the text from Find dialog box which I wish to search
- Get the text from main Edit control
- Do a substring search from the last offset (don't start from beginning every time)
- Find the position of a result and readjust offset
- Select the found text
I know I haven't really asked a direct question here, well I guess the direct question would be: How do I make this work? :) But more importantly it would be to understand how this exactly works. I'd appreciate if you can provide me with an elaborate answer. Thanks for all the help!
It looks like you're very close, you just need to get the hwndEdit from your main window. You passed your main window's handle in as a parent to your dialog box, so you should be able to get the parent window of your dialog box like so:
HWND hwndParent = GetParent(hDlg);
After that you can get the edit control from that parent by referencing the edit control ID in your main window definition. Something like this (assuming the control ID is IDC_EDIT):
HWND hwndEdit = GetDlgItem(hwndParent, IDC_EDIT);