how to create tooltips with arabic text in mfc application - visual-c++

I want to create a simple MFC application which uses the RTL property to display a tooltip with the given Arabic text content for an edit box in the application dialog.
My code looks like this:
HWND CMFCApplicationDlg::CreateToolTip(HWND hWnd, LPCTSTR szText){
hWndTT = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
m_hWnd,
NULL,
GetModuleHandle(NULL),
NULL);
if(!hWndTT)
{
return NULL;
}
if (szText == NULL)
{
::DestroyWindow(hWndTT);
hWndTT = NULL;
return NULL;
}
// Set up the tool information. In this case, the "tool" is the entire parent window
toolItem.cbSize = sizeof(toolItem);
toolItem.uFlags = TTF_IDISHWND | TTF_SUBCLASS | TTF_RTLREADING;//Setting RTL flag here
toolItem.hwnd = m_hWnd;
toolItem.hinst = GetModuleHandle(NULL);
toolItem.lpszText = (wchar_t *)szText;
toolItem.uId = (UINT_PTR)hWnd;
::GetClientRect(hWnd, &toolItem.rect);
// Associate the tooltip with the tool window
LRESULT result = ::SendMessage(hWndTT, TTM_ADDTOOL, 0, (LPARAM)&toolItem);
return hWndTT;
}
I'm calling this function from OnInitDialog() method this way:
CreateToolTip((HWND)GetDlgItem(IDC_EDIT_DUMMY), L".استخدم 2 من المرات في اليوم");
Here IDC_EDIT_DUMMY is the ID for the edit box that I am trying to attach the tooltip with. But for some reason, the application doesn't display the tooltip at all. Where am I going wrong?

The MFC has it's own tooltip implementation. May be it is easier to use this instead of using the plain Win32 tooltips.
You can use CWnd::EanableTooltips to activate it. The MSDN doku (see link contains a full sample)
Also code project has a sample for it.

Related

Get all control IDs of MFC dialog box

Is there some way to get all control IDs of current MFC dialog box? (to change WindowText of all controls)
You can do something like that:
for(CWnd* pWnd = GetWindow(GW_CHILD); pWnd != NULL; pWnd = pWnd->GetWindow(GW_HWNDNEXT))
{
pWnd->SetWindowText(_T("MyText"));
}
Of course, you can check ID or type of control id if you need.

Search Bar style changes in Xamarin Forms

I need to use Search Bar in my application for both Xamarin Android and Xamarin iOS.
I have to achieve below search bar in my application.
Please find code used in xaml,
<Frame Padding="0" OutlineColor="DarkGray" HasShadow="True" HorizontalOptions="FillAndExpand" VerticalOptions="Center">
<SearchBar x:Name="searchBar" Placeholder="Search" PlaceholderColor="LightGray" TextColor="#000000" HorizontalOptions="FillAndExpand" VerticalOptions="Center" TextChanged="SearchBar_TextChanged"/>
</Frame>
My search bar look like below, Need to remove the highlighted line from xamarin android.
Also find search bar renderer code,
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
var color = global::Xamarin.Forms.Color.LightGray;
var searchView = (Control as SearchView);
var searchIconId = searchView.Resources.GetIdentifier("android:id/search_mag_icon", null, null);
if (searchIconId > 0)
{
var searchPlateIcon = searchView.FindViewById(searchIconId);
(searchPlateIcon as ImageView).SetColorFilter(color.ToAndroid(), PorterDuff.Mode.SrcIn);
}
var symbolView = (Control as SearchView);
var symbolIconId = symbolView.Resources.GetIdentifier("android:id/search_close_btn", null, null);
if(symbolIconId>0)
{
var symbolPlateIcon = symbolView.FindViewById(symbolIconId);
(symbolPlateIcon as ImageView).SetColorFilter(color.ToAndroid(), PorterDuff.Mode.SrcIn);
}
}
Xamarin Android:
I have used frame control to show border in Search Bar. I have to remove search bar border bottom line or border color in it.
Xamarin iOS:
I have to acheive search bar control as seems in picture. I have to remove cancel word shown in search bar while searching in it. Also need to remove radius around in it.
Anyone suggest on this?
In Android, you could find the search_plate via id and set it to Transparent, like this:
if (Control != null)
{
var color = global::Xamarin.Forms.Color.LightGray;
var searchView = Control as SearchView;
int searchPlateId = searchView.Context.Resources.GetIdentifier("android:id/search_plate", null, null);
Android.Views.View searchPlateView = searchView.FindViewById(searchPlateId);
searchPlateView.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
In iOS, you could find the Textfield of UISearchBar, then customize the border style of it. And remove the "Cancel" button via setting ShowsCancelButton to false. For example, like this:
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (Control != null)
{
Control.ShowsCancelButton = false;
UITextField txSearchField = (UITextField)Control.ValueForKey(new Foundation.NSString("searchField"));
txSearchField.BackgroundColor = UIColor.White;
txSearchField.BorderStyle = UITextBorderStyle.None;
txSearchField.Layer.BorderWidth = 1.0f;
txSearchField.Layer.CornerRadius = 2.0f;
txSearchField.Layer.BorderColor = UIColor.LightGray.CGColor;
}
}

CDockablePane doesn't save layout when it's docked to another pane

In an MFC application, I've got two derived CDockablePane pane objects docked to either side of the main view.
Here is the code to create one of the panes. The second is similar.
if(m_dlgPane && m_dlgPane->GetSafeHwnd())
{
m_dlgPane->ShowPane(TRUE,FALSE,TRUE);
//RecalcLayout();
return ;
}
m_dlgPane = new CDialogPane;
((CDialogPane*)m_dlgPane)->m_wndDlg = new CPaneChildDlg();
((CDialogPane*)m_dlgPane)->nDlgID = CPaneChildDlg::IDD;
UINT style = WS_CHILD | CBRS_RIGHT | CBRS_FLOAT_MULTI;
CString strTitle = _T("Child Dialog Pane");
if (!m_dlgPane->Create(strTitle, this, CRect(0, 0, 300, 400), TRUE,
IDC_DIALOG_PANE, style,AFX_CBRS_OUTLOOK_TABS))
{
TRACE0("Failed to create dialog pane\n");
SAFE_DELETE(m_dlgPane);
return ;
}
m_dlgPane->EnableDocking(CBRS_ALIGN_ANY);
DockPane((CBasePane*)m_dlgPane,AFX_IDW_DOCKBAR_RIGHT);
m_dlgPane->ShowPane(TRUE, FALSE, TRUE);
m_dlgPane->RecalcLayout();
The layouts are saved by windows through LoadState & SaveState methods. And are called by the framework.
BOOL CDialogPane::SaveState(LPCTSTR lpszProfileName, int nIndex, UINT uiID)
{
return CDockablePane::SaveState(lpszProfileName, nIndex, uiID);
}
BOOL CDialogPane::LoadState(LPCTSTR lpszProfileName, int nIndex, UINT uiID)
{
return CDockablePane::LoadState(lpszProfileName, nIndex, uiID);
}
The layouts loaded properly each time application launches. Apart from when one pane(Pane2) is docked to the other one(Pane1). It seems that it doesn't remember or load the correct height of the Pane2. Although this works throughout the application lifetime but not when the application exists and opens again.

Splitting Child Window in MFC MDI Program

I am trying to split the Child Window of an MFC MDI progarm that I am working on but am having some problems. I know I have to use the CSplitterWnd class and have been trying to follow the instructions on the post here:
Create multi views in a CChildFrame using CSplitterWnd
but can't seem to get it to work, would anyone be able to offer me some advice with regard to these instructions, I have some specific questions:
Is CRightView also a CView derived class and what code should go in there if any?
Are m_pLeftView, m_pRightView, m_pPhongView and m_pPhongInfo all variables of the appropriate classes and do they have any particular type?
Where does CTreeView come from, does not seem to be a standard base class?
rc.Width in CChildFrame::OnCreateClient gives an undeclared identifier error, is there something I should be declaring somewhere here?
I would appreciate any advice about this, really struggling to get the splitter to work.
Thanks
After working on it for a couple of days I've managed to solve my own problem, I'm adding the solution here for anyone else who might have the same problem.
Declare the two view classes, in my case CElement View which is a CWnd derived class and CSampleViewer3dView which is a CView derived class.
In CChildFrame add a variable with access private, type CSplitterWnd and name m_wndSplitter.
Add an override for the OnCreateClient function in CChildFrame, this should add the code:
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
to ChildFrm.h, you should also add a boolean flag m_bInitSplitter to ChildFrm.h:
BOOL m_bInitSplitter;
you also have to add:
m_bInitSplitter = false;
to the constructor of ChildFrm.cpp, the following code is added to ChildFrm.cpp when you add the variable using the wizard:
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
}
Put the following code into CChildFrame::OnCreateClient:
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
CRect cr;
GetWindowRect( &cr );
if (!m_wndSplitter.CreateStatic(this, 1, 2))
{
MessageBox("Error setting up splitter frames!", "Init Error!", MB_OK | MB_ICONERROR);
return FALSE;
}
if (!m_wndSplitter.CreateView( 0, 0, RUNTIME_CLASS(CElementView),
CSize(cr.Width()/2, cr.Height()), pContext ) )
{
MessageBox("Error setting up splitter frames!", "Init Error!", MB_OK | MB_ICONERROR);
return FALSE;
}
if (!m_wndSplitter.CreateView( 0, 1, RUNTIME_CLASS(CSampleViewer3dView),
CSize(cr.Width()/2, cr.Height()), pContext))
{
MessageBox("Error setting up splitter frames!", "Init Error!", MB_OK | MB_ICONERROR);
return FALSE;
}
m_bInitSplitter = TRUE;
return TRUE;
}
Add an override for the WM_SIZE message to CChildFrame and insert the following code:
void CChildFrame::OnSize(UINT nType, int cx, int cy)
{
CMDIChildWnd::OnSize(nType, cx, cy);
CRect cr;
GetWindowRect(&cr);
if (m_bInitSplitter && nType != SIZE_MINIMIZED)
{
m_wndSplitter.SetRowInfo( 0, cy, 0 );
m_wndSplitter.SetColumnInfo(0, cr.Width()*0.25 / 2, 50);
m_wndSplitter.SetColumnInfo(1, cr.Width()*0.75 / 2, 50);
m_wndSplitter.RecalcLayout();
}
}
You can edit the size of each window by changing the values of 0.25 and 0.75 to the required percentage of the screen that you want each view to take up.
Add header files for the two views to ChildFrm.cpp, e.g. ElementView.h and SampleViewer3dView.h.
You should then have two independent views in the child window of an MDI program.

Is there a Form.Showdialog equivalent for Gtk# Windows?

Using Windows Forms or WPF I can open a dialog window by calling ShowDialog. How can I do that using Gtk#?
I tried just making the Window modal, but although it prevents the user from interacting with the calling window it does not wait for the user to close the dialog before running the code after ShowAll().
Instead of using a Gtk.Window, use Gtk.Dialog, then call dialog.Run (). This returns an integer value corresponding to the ID of the button the user used to close the dialog.
e.g.
Dialog dialog = null;
ResponseType response = ResponseType.None;
try {
dialog = new Dialog (
"Dialog Title",
parentWindow,
DialogFlags.DestroyWithParent | DialogFlags.Modal,
"Overwrite file", ResponseType.Yes,
"Cancel", ResponseType.No
);
dialog.VBox.Add (new Label ("Dialog contents"));
dialog.ShowAll ();
response = (ResponseType) dialog.Run ();
} finally {
if (dialog != null)
dialog.Destroy ();
}
if (response == ResponseType.Yes)
OverwriteFile ();
Note that Dispose()ing a widget in GTK# doesn't Destroy() it in GTK# -- a historical design accident, preserved for backwards-compatibility. However, if you use a custom dialog subclass you can override Dispose to also Destroy the dialog. If you also add the child widgets and the ShowAll() call in the constructor, you can write nicer code like this:
ResponseType response = ResponseType.None;
using (var dlg = new YesNoDialog ("Title", "Question", "Yes Button", "No Button"))
response = (ResponseType) dialog.Run ();
if (response == ResponseType.Yes)
OverwriteFile ();
Of course, you could take it a step further and write an equivalent of ShowDialog.
I'm trying to create a more complex dialog, one that doesn't have windows - it's a search dialog with a completion treeview nested in a scrollview, and is closed with Enter or Escape.
Here's how I've figured you put together the mechanics of a modal dialog manually:
Define a property on your dialog that indicates whether it is completed or not. I'm calling mine ModalResult, an enum with values None, OK and Cancel.
Ensure you have the parent window of the dialog handy (dialogParent below)
Sample code:
// assuming Dispose properly written per #mhutch
using (window = new MyDialogWindow())
{
window.TransientFor = dialogParent;
window.Modal = true;
window.Show();
while (window.ModalResult == ModalResult.None)
Application.RunIteration(true);
// now switch on value of modal result
}
Note however this Ubuntu bug with overlay scrollbars. I don't use them and my app is for personal use, but YMMV.
I implemented the following method on my Gtk.Dialog:
public ResponseType ShowDialog()
{
List<ResponseType> responseTypes = new List<ResponseType>
{
// list all the ResponseTypes that you have buttons for
// or that you call this.Respond(...) with
ResponseType.Ok,
ResponseType.Cancel
};
this.Modal = true;
// start with any ResponseType that isn't contained in responseTypes
ResponseType response = ResponseType.None;
while (!responseTypes.Contains(response))
{
response = (ResponseType)this.Run();
}
this.Destroy();
return response;
}

Resources