I'm just wondering what the modern equivalent of:
NSNotificationCenter.DefaultCenter.AddObserver("UIDeviceOrientationDidChangeNotification", receivedRotate);
would be. It says its obsolete and that I should use AddObserver, but I'm not sure what to use for the IntPtr context var.
You don't need the IntPtr variant, if you read the Obsolete method it says:
"Use AddObserver(NSString, Action) instead"
So what you want is
NotificationCenter.DefaultCenter.AddObserver (UIDevice.OrientationDidChangeNotification, receivedRotate);
Related
How to convert System::string^ in to LPCTSTR ?
As my requirement is to clone a file using function CopyFile, it works fine if i give Fix name (OldFile.jpg and LatestFile.jpg) to its parameters (below Code: Works Fine)
LPCTSTR in_f,out_f;
in_f = _T("d:\\Old.jpg");
out_f = _T("d:\\Latest.jpg");
CopyFile(in_f,out_f,false);
above code clone the Old.jpeg in to a Latest.jpg but when i trying to give name (Latest.jpg) which is coming out from some String it won't create file (below Code: NOT Working)
String^ Name = "Latest";
//------Capture Current Date & Time
DateTime datetime = DateTime::Now;
//-------Convert Date Timt in to String
Name = Name + String::Format("{0}",datetime);
Name = Name->Replace('/','-');
Name = Name->Replace(':','-');
Name = Name + ".jpg";
LPCTSTR in_f,out_f;
in_f = _T("d:\\Old.jpg");
out_f = (LPCTSTR)Name; //Trying to Assign Current Latest file Name With date Time here
CopyFile(in_f,out_f,false);
The Problem is CopyFile Took LPCTSTR type as an argument , where as i am giving a type System::string^, So suggest me how to convert this System::string^ in to LPCTSTR so that i can add the current date time with in the name of my file.
I am Using VC++2010 and Windows form Application
Standard warning: While it's certainly possible to write the main body of your application in C++/CLI, or even write the GUI in C++/CLI using WinForms, it is not recommended. C++/CLI is intended for interop scenarios: where C# or other .Net code needs to interface with unmanaged C++, C++/CLI can provide the translation between the two. For primary development, it is recommended to use C# with either WinForms or WPF if you want managed code, or C++ with MFC if you want unmanaged.
I'm not sure I agree with Hans's comment that TCHAR is obsolete, but doing an explicit conversion to a wide string and calling CopyFileW is a good option.
Also, one could go the other direction, and convert from unmanaged to managed strings, and use the .Net method to copy files, File::Copy(String^, String^, Boolean).
To convert to a LPCTSTR, I would use marshal_as. Because it's implemented with templates, the compiler will resolve your LPCTSTR to call either the LPCSTR or LPCWSTR version, as appropriate.
Microsoft doesn't have dedicated documentation pages for each templated version of marshal_as, but the Overview of Marshaling in C++ page is a good place to start.
My test program:
#include <msclr\marshal.h>
int main(array<System::String^>^ args)
{
String^ managedStr = "I came from managed land!\r\n";
// This controls the lifetime of the LPCTSTR that marshal_as returns.
// When this goes out of scope, the LPCTSTR will no longer be valid,
// so be aware of its lifetime.
msclr::interop::marshal_context context;
LPCTSTR unmanagedStr = context.marshal_as<LPCTSTR>(managedStr);
OutputDebugString(unmanagedStr);
return 0;
}
Result:
I came from managed land!
You need to append a \0 character at the end of the Name string, since CopyFile() expects zero-terminated strings.
EDIT: As LucasTrzesniewski has pointed out, pinning a .NET string automatically yields a zero-terminated character array. This is documented in the C# specification. See the comments below for more information.
Moreover, you have to "pin" the string in memory, so the garbage collector won't move it around. Then you can create a pointer to the first character of the string. C++/CLI provides some utility types and functions to do this. Here's an example:
pin_ptr<const WCHAR> psName = PtrToStringChars (Name)
PtrToStringChars() is an inline function declared in vcclr.h. psName should be assignable to a LPCTSTR parameter - if not, use a cast. Note that PtrToStringChars() doesn't work if the input string is a nullptr. You need to test explicitly for this case. (However, in your case, Name is certainly not a nullptr).
The String remains pinned until the variable psName gets out of scope. This happens after leaving the { ... } block in which it's declared, e.g. after leaving the current function. No explicit unpinning is needed.
You need to marshaling it to "const char *" and make a static_cast to LPCTSTR.
Take a look at this https://msdn.microsoft.com/en-us/library/bb384865.aspx
PHP 7.1 will introduce the void function type.
https://wiki.php.net/rfc/void_return_type
In which cases is it useful to explicitly specify that a function is a "void" type instead of simply return; without any precision?
This would be helpful to the developers working on the project for a few reasons.
Provides a clear indication that the function does not return a value
The above could equally apply to auto-generated docs
Could be used for unit testing
Could help prevent coding errors, where a developer accidentally tries to return, or expect, a value
using MFC and Unicode-Build
i want to change the colum-header-text of a listctrl and to do so i have to convert an LPCTSTR to an LPWSTR. what i do now is
void CSPCListViewCtrl::SetHeaderText(long lCol, LPCTSTR lColText)
{
CListCtrl& ListCtrl = GetListCtrl();
LV_COLUMN lvc;
::ZeroMemory((void *)&lvc, sizeof(LVCOLUMN));
lvc.mask |= LVCF_TEXT;
ListCtrl.GetColumn(lCol, &lvc);
lvc.pszText = const_cast<LPWSTR>(lColText);
ListCtrl.SetColumn(lCol, &lvc);
}
it seems to work but the const_cast looks somewhat strange and wrong to me so i tried out something like
USES_CONVERSION;
lvc.pszText = CT2W(lColText);
this seems to work in release-build but produces garbage in debug-build so i wonder what is the correct way to do it?
TL;DR: Using const_cast<LPTSTR>(lColText) is safe when calling CListCtrl::SetColumn.
But why then is the pszText member of the LVCOLUMN structure declared non-const? The LVCOLUMN structure is used both to set and retrieve information. When retrieving a column's text, you need to pass in a modifiable buffer (and length argument). When setting a columns text, on the other hand, the system uses the pszText member and internally stores a copy. It does not attempt to write to it. This is documented as well, even if very subtly:
cchTextMax
Size in TCHARs of the buffer pointed to by the pszText member. If the structure is not receiving information about a column, this member is ignored.
This is a common pattern in the Windows API, where the same structure is used both as an input and output parameter. The only option to work around this would have been to introduce a const-ified version for those structures. When the Windows API was invented 30 years ago, this wasn't deemed necessary or useful. Besides, it would have made a common pattern (read-update-write) more tedious and error prone, as the data would have to be manually copied between unrelated types.
Now that you know, that using a const_cast is safe in the scenario you described, you may be wondering, if it is a good idea to use it. That depends on a number of factors, e.g.
Can you come up with a helpful comment to concisely explain, why this is ok? Something along the lines of // Totally safe, it's just that M$ sucks probably won't cut it.
Will all members on your team understand the implications, or will this present a red herring in heap corruption debug sessions?
Do you have coding guidelines that allow the use of const_casts?
Are you using static code analysis tools that won't produce false positives for const_casts?
If you find that you cannot satisfactorily answer all those questions, you may consider implementing (technically unnecessary) manual copying (and exchange a const_cast for exception handling):
void CSPCListViewCtrl::SetHeaderText(long lCol, LPCTSTR lColText) {
CListCtrl& ListCtrl = GetListCtrl();
LVCOLUMN lvc = {0};
lvc.mask |= LVCF_TEXT;
// Create modifiable copy of lColText
size_t colTextLength = _tcslen(lColText);
std::vector<TCHAR> buffer(colTextLength + 1);
std::copy(lColText, lColText + colTextLength + 1, buffer.data());
lvc.pszText = buffer.data();
ListCtrl.SetColumn(lCol, &lvc);
}
One more note on your use of character string encodings: You are mixing the use of Generic-Text Mappings with explicit Unicode (UTF-16LE) encoding. To add consistency, you should change the lColText argument to type LPCWSTR, and use an LVCOLUMNW structure (as well as a const_cast<LPWSTR> if you decide to go that route). Unfortunately, when using MFC, you will have to resort to using the generic-text mappings when calling any class members. But at least you will get a compiler error in case of mismatching character encodings.
You can use CString::GetBuffer()
void SetHeaderText(long lCol, LPCTSTR lColText)
{
LV_COLUMN lvc;
::ZeroMemory((void *)&lvc, sizeof(LVCOLUMN));
lvc.mask |= LVCF_TEXT;
list.GetColumn(lCol, &lvc);
CString str = lColText;
lvc.pszText = str.GetBuffer();
list.SetColumn(lCol, &lvc);
str.ReleaseBuffer();
//ReleaseBuffer is option in this case because
//"str" is local variable and is destroyed before being used again*
}
SetHeaderText(0, L"text");
In UNICODE, LPTSTR is just LPWSTR (or simply wchar_t*)
If for some reason you have ANSI text, then you can use CString for conversion
CStringA ansi = "Text";
CStringW wide = CStringW(ansi);
SetHeaderText(0, wide);
See also
CString::GetBuffer()
Currently I'm experimenting with C#4's dynamic programming and I did not completely understand under which circumstances the keyword dynamic works. It is clear to me that it works with IDispatch, as it allows to inform the caller with type information automatically. But shouldn't it also work with IUnknown and a type lib? (In http://samgentile.com/Web/vs2010-and-net-framework-4-0/c-4-0-bcl-4-series-dynamic-primitive-type-part-1/ I found a vague hint that a Binding to IUnknown should be possible.)
IUnknown w/o typelib: should not work, the interfaces must be written in C# explicitly, so I didn't try it. (Confirmed by Hans Passant in C# 4.0 dynamic object and WinAPI interfaces like IShellItem (without defining them in the C# source).)
IUnknown w/ type lib: I have completely no idea, if it works and how it works as I found no clear information. (I linked the type lib into the COM dll, but the DLR could not bind methods.)
So does IUnknown w/ type lib work with C#'s dynamic keyword? - If so, what do I have to do?
My current foundings are that the COM-binder only works with IDispatch and not with IUnknown at all.
I'm localizing an MFC app into Japanese, and have the resources working right.
My current problem is that, when I use AfxMessageBox or MessageBox, the dialog title and button messages come up in English, and I haven't found anywhere to change that.
I haven't found anything useful searching MSDN or Google.
So,
Does this work? Does Windows come up with "OK" or "Yes/No" buttons in Japanese, Arabic, and Russian?
If not, what do I specify to change these?
Edit: I went with MessageBoxEx, writing a wrapper class to make it as convenient to use as AfxMessageBox. It does appear that MB_OK comes up as "OK" in both English and Japanese, but other button options like MB_YESNO are translated into something that I assume is correct Japanese. This was a fairly small application to translate, and we might want to use something automated for the larger ones.
Use MessageBoxEx and specify the WORD wLanguageId field.
wLanguageId
[in] Specifies the language for the text displayed in the message box
button(s). Specifying a value of zero
(0) indicates to display the button
text in the default system language.
If this parameter is
MAKELANGID(LANG_NEUTRAL,
SUBLANG_NEUTRAL), the current language
associated with the calling thread is
used.
To specify a language other than the current language, use the
MAKELANGID macro to create this
parameter. For more information, see
MAKELANGID.
More information on MAKELANGID can be found here.
If this does not work well for you, the alternative would be to make your own dialog box.
The title is a string you specify, so you should be able to translate it.
In AfxMessageBox(), the title is the application name (AfxGetAppName() IIRC).
Regarding the buttons, the text is part of the OS and cannot be translated.
MessageBoxEx (mentioned by Brian) never worked well regarding languages support. This MS KB article from over a decade ago says the language id will be correctly supported by Windows 2000. But it obviously never made it through.
So you're pretty much out of luck. Your only solution would be to use a 3rd party implementation such as the excellent XMessageBox and provide translations through your string table.
Note that appTranslator's glossary contains words such as Yes, no, cancel,... in 25 languages and would translate them automatically.
Create your own L10N macros/function and use this code:
static LRESULT __stdcall ChangeCaptions(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_ACTIVATE) {
SetWindowText(GetDlgItem((HWND) wParam, IDOK), L10N(GUI_OK_MSG));
SetWindowText(GetDlgItem((HWND) wParam, IDCANCEL), L10N(GUI_CANCEL_MSG));
SetWindowText(GetDlgItem((HWND) wParam, IDYES), L10N(GUI_YES_MSG));
SetWindowText(GetDlgItem((HWND) wParam, IDNO), L10N(GUI_NO_MSG));
}
return 0;
}
int addon_gui_messagebox(HWND parentHWnd, HINSTANCE hInstance, void *text, void *caption, int type)
{
int ret;
hook = SetWindowsHookEx(WH_CBT, ChangeCaptions, hInstance, GetCurrentThreadId());
ret = MessageBox(parentHWnd, text, caption, type);
UnhookWindowsHookEx(hook);
return ret;
}
As I wrote previously MessageBoxEx currently ignore lang arg.