Find localized Windows strings - windows

I need to find some strings that the current version of Windows is using. For example, when I create a new folder, it is initially named "New Folder" on English Vista. I need to programmatically find what that folder would be named on any language and version of Windows that I might be running on.
Anyone have any ideas how to do that?
Thanks Morinar -- I just stumbled upon that article too. Unfortunately, the stringID doesn't appear to be constant -- it's 30396 on my Vista, which isn't the same as what they show for XP. So it would appear MS didn't keep it stable.
EDIT: Looks like this isn't possible...? This apps runs on computers in Germany, The Netherlands, France, Spain, Brazil, Mexico, Vietnam, Taiwan, China, Japan, South Korea, India, Israel, Hungary ... You get the idea. It will take a very long time to install all the different language packs and find out what 'New Folder' is in every language.
Perhaps the best option is to default to "New Folder" and make the user change that value if they want to. I just prefer to have the software figure out as much as it can and spare the user from configuring _yet_another_setting_.

Shamelessly cribbed from http://blogs.msdn.com/oldnewthing/archive/2004/01/30/65013.aspx. This is mostly correct but if there is a resource string of "New Folder something else" it will match that:
LPCWSTR FindStringResourceEx(HINSTANCE hinst,
UINT uId, UINT langId)
{
// Convert the string ID into a bundle number
LPCWSTR pwsz = NULL;
HRSRC hrsrc = FindResourceEx(hinst, RT_STRING,
MAKEINTRESOURCE(uId / 16 + 1),
langId);
if (hrsrc) {
HGLOBAL hglob = LoadResource(hinst, hrsrc);
if (hglob) {
pwsz = reinterpret_cast<LPCWSTR>
(LockResource(hglob));
if (pwsz) {
// okay now walk the string table
for (int i = 0; i < (uId & 15); i++) {
pwsz += 1 + (UINT)*pwsz;
}
pwsz+= 1;
}
}
}
return pwsz;
}
UINT FindResourceStringId(HMODULE resource_handle, LPCWSTR string, UINT langId)
{
UINT resource_id= -1;
for (int i= 0; i<65536; ++i)
{
LPCWSTR resource_string= FindStringResourceEx(resource_handle, i, langId);
if (resource_string && wcsncmp(resource_string, string, wcslen(string))==0)
{
resource_id= i;
}
}
return resource_id;
}
int main()
{
HMODULE shell_handle= LoadLibraryW(L"shell32.dll");
UINT new_folder_id= FindResourceStringId(shell_handle, L"New Folder", 0x409); // look for US English "New Folder" resource id.
}

This is not easy. These strings are private data for Windows Explorer, and as such they can (and probably do) change between releases. You can hack something up where you do a lot of version checking and read the appropriate resource string, but that seems like a losing battle. What are you trying to accomplish?

Unsure if there is a more elegant way or not (I couldn't seem to find one), but those strings are stored in %windir%\System32\Shell32.dll. Theoretically, you could merely read that file in and extract the appropriate strings.
Seems a bit hacky-ish, but should get the job done. Here's a link to an article that discusses where they live in said file:
http://www.askvg.com/customize-new-folder-and-new-shortcut-text-in-windows-xp/
Seems like there could or even should be an interface to them via the Windows API, but trolling through the documentation I couldn't find one. Perhaps you'll have more luck.

If you want to handle 80% of the cases, you can start with "New Folder".
As I guess you're in an enterprise environment, you can get the folder names back into a storage, then after a week (or any time) you get through the names; update your app; release the new version which will please the users. (then later publish the results here)
You can preemptively test your app on a range of platform you're suspecting the users to use. to get a first series of folders names.
This will avoid the problem of dealing with code specific with each of the platform you're looking at.
EDIT
Well I get a second thought about that, I guess you might want to warn the user about that "New Folder" if it wasn't rename after some time (say a minute)? then I guess you would need to add a list and a timer ...

Related

Updating display of directory/folder path in MFC File-Open dialog [duplicate]

I'm trying to make a 'Save As' dialog with an event that would change the default path based on the type of file we choose from the filters combo box. The problem is, all the examples I've seen execute the code on result IDOK or IDCANCEL while I'd need the code to be executed while the dialog is still opened.
Also, is there any way to differentiate between what filter has been chosen if the filters have the same type? The GetFileExt() method just returns the extension but I have no way of telling if it was the first .my filter or the template .my filter.
I've seen something like LPOFNHOOKPROC but there was no example of how would I even use it and I'm not sure whether it would even solve my problem or not.
void CMyClass::OnFileOpen()
{
CString pathNam;
CString fileName;
TCHAR szFilters[]= _T("MyType Files (*.my)|*.my|Template MyType (*.my)|*.my||");
CFileDialog fileDlg(TRUE, _T("my"), _T("*.my"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);
if(fileDlg.DoModal() == IDOK)
{
pathName = fileDlg.GetPathName();
fileName = fileDlg.GetFileTitle();
}
}
EDIT:
I am now able to get the specific filter that's been chosen by getting the OFN and checking the nFilterIndex value. So the remaining problem is whether I can update the path based on the chosen file format?
EDIT2:
I've found the OnChangeType method and overloaded it in the subclass and it indeed executes the method and the code within, but when I try to update the file path I get an access violation:
void TFileDialogExt::OnTypeChange()
{
LPWSTR buff = L"C:\\TEST\\template.my";
if(m_pOFN->nFilterIndex == 2)
m_ofn.lpstrFile = buff;
}
Basically you have to subclass CFileDialog and handle its CFileDialog::OnTypeChange method.
But, as suggested by Microsoft: you'd better use a new Common Item Dialog instead.
I did some research about this and found some useful questions:
Programmatically pre-select using IFileDialog in C++
How to use SHCreateItemFromParsingName with names from the shell namespace?
Also, have a look at: SHCreateItemFromParsingName.
Here is a sample OnTypeChange handler:
void CMyFileDialog::OnTypeChange()
{
{
IFileOpenDialog* pfod = NULL;
HRESULT hr = (static_cast<IFileDialog*>(m_pIFileDialog))->QueryInterface(IID_PPV_ARGS(&pfod));
if (SUCCEEDED(hr))
{
IShellItem* psiInitialDir;
CString strFolder = L"d:\\";
hr = SHCreateItemFromParsingName(strFolder.GetString(), NULL, IID_PPV_ARGS(&psiInitialDir));
if(SUCCEEDED(hr))
{
pfod->SetFolder(psiInitialDir);
}
}
}
CFileDialog::OnTypeChange();
}
My code uses a hard coded path for testing purposes, but you should now be able to complete your code:
Determine which path you want to use based on the currently selected filter index.
Use similar logic as here to navigate to that folder.

Can I update a message field from enum to string, and keep its name?

The Code
Consider the following protobuf message declaration:
syntax = "proto3";
enum Airport {
TLV = 0;
JFK = 1;
...
}
message Flight {
...
Airport origin_airport = 11;
...
}
The Problem
Due to some business requirements, we have to set the Airport to be a free string rather than choosing from a closed enumerated list. I know that I can add and remove fields at will, as long as I don't reuse the same number. However, I'm not sure if I can use the same name, a-la:
message Flight {
...
reserved 11; // The old enum field number
string origin_airport = 18; // Unused so far
...
}
My Question
Upon updaing a protobuf3 field type, can the field name be preserved, as long as its number changes?
If you aren't using the JSON variant, then names aren't used at all in the payload, so yes technically it is perfectly legal to reuse names; however: this might lead to unnecessary problems with existing code - depending on existing code and language / framework specific rules, and could cause confusion. Since that is avoidable, I would advocate using a name like origin_airport_code, or similar.
(The point I'm making here: any code that used the old field probably needs attention; I can see some scenarios where the existing code might still compile after the change, but mean something different, and therefore introduce a bug that would have been avoided if you'd changed the name and forced every usage to be visited)

How to get the timestamp of when a disk is made offline from diskmgmt or other ways in windows?

I want to know the time when a disk is made offline by user. Is there a way to know this through WMI classes or other ways?
If you cannot find a way to do it through the Win32 API/WMI or other, I do know of an alternate way which you could look into as a last-resort.
What about using NtQueryVolumeInformationFile with the FileFsVolumeInformation class? You can do this to retrieve the data about the volume and then access the data through the FILE_FS_VOLUME_INFORMATION structure. This includes the creation time.
At the end of the post, I've left some resource links for you to read more on understanding this so you can finish it off the way you'd like to implement it; I do need to quickly address something important though, which is that the documentation will lead you to
an enum definition for the _FSINFOCLASS, but just by copy-pasting it from MSDN, it probably won't work. You need to set the first entry of the enum definition to 1 manually, otherwise it will mess up and NtQueryVolumeInformationFile will return an error status of STATUS_INVALID_INFO_CLASS (because the first entry will be identified as 0 and not 1 and then all the entries following it will be -1 to what they should be unless you manually set the = 1).
Here is the edited version which should work.
typedef enum _FSINFOCLASS {
FileFsVolumeInformation = 1,
FileFsLabelInformation,
FileFsSizeInformation,
FileFsDeviceInformation,
FileFsAttributeInformation,
FileFsControlInformation,
FileFsFullSizeInformation,
FileFsObjectIdInformation,
FileFsDriverPathInformation,
FileFsVolumeFlagsInformation,
FileFsSectorSizeInformation,
FileFsDataCopyInformation,
FileFsMetadataSizeInformation,
FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
Once you've opened a handle to the disk, you can call NtQueryVolumeInformationFile like this:
NTSTATUS NtStatus = 0;
HANDLE FileHandle = NULL;
IO_STATUS_BLOCK IoStatusBlock = { 0 };
FILE_FS_VOLUME_INFORMATION FsVolumeInformation = { 0 };
...
Open the handle to the disk here, and then check that you have a valid handle.
...
NtStatus = NtQueryVolumeInformationFile(FileHandle,
&IoStatusBlock,
&FsVolumeInformation,
sizeof(FILE_FS_VOLUME_INFORMATION),
FileFsVolumeInformation);
...
If NtStatus represents an NTSTATUS error code for success (e.g. STATUS_SUCCESS) then you can access the VolumeCreationTime (LARGE_INTEGER) field of the FILE_FS_VOLUME_INFORMATION structure with the FsVolumeInformation variable.
Your final task at this point will be using the LARGE_INTEGER field named VolumeCreationTime to gather proper time/date information. There are two links included at the end of the post which are focused on that topic, they should help you sort it out.
See the following for more information.
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntifs/nf-ntifs-ntqueryvolumeinformationfile
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ne-wdm-_fsinfoclass
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/ns-ntddk-_file_fs_volume_information
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724280.aspx
https://blogs.msdn.microsoft.com/joshpoley/2007/12/19/datetime-formats-and-conversions/

Processing: KeyPressed and displaying new set of Data (using same key)?

I was wondering how I would go about getting a different set of data to print every time I press the same key for KeyPressed in Processing. The data being displayed is from an imported file so the code for what I'm doing is as follows:
import java.util.Scanner;
import java.io.*;
PImage cityMap;
FileInputStream in;
int Year=0;
void setup()
{
size(500,500);
cityMap=loadImage("cityMap.png");
background(cityMap);
}
void draw()
{
//EMPTY
}
void keyPressed() {
if(key==CODED)
{
if(keyCode==RIGHT)
{
//2015
String fif[]= loadStrings("2015data.txt");
for (int i=1; i<fif.length;i++)
{
Scanner sc= new Scanner(fif[i]);
int xValue= sc.nextInt();
int yValue= sc.nextInt();
int pixelX= locX2PixX(xValue);
int pixelY= locY2PixY(yValue);
stroke(200,200,250);
point(pixelX,pixelY);
}
//2016
String six[]= loadStrings("2016data.txt");
if(
for (int i=1; i<six.length;i++)
{
Scanner sc= new Scanner(six[i]);
int xValue= sc.nextInt();
int yValue= sc.nextInt();
int pixelX2= locX2PixX(xValue);
int pixelY2= locY2PixY(yValue);
stroke(250,200,250);
point(pixelX2,pixelY2);
}
//2017
String seven[]= loadStrings("2017data.txt");
for (int i=1; i<seven.length;i++)
{
Scanner sc= new Scanner(seven[i]);
int xValue= sc.nextInt();
int yValue= sc.nextInt();
int pixelX3= locX2PixX(xValue);
int pixelY3= locY2PixY(yValue);
stroke(20,200,250);
point(pixelX3,pixelY3);
}
}
}
}
int locX2(int locationX)
{
return((int)((6*locationX)-8));
}
int locY2(int locationY)
{
return((int)(8*locationY+8));
}
I managed to get the code to run minus that one feature.
I think I have most of the logic down, I'm just trying to figure out to have this show only one set of the data at a time and then the next one after I press the same key again. I was thinking I may need some type of if statement that could maybe use my year variable?
(I don't know that much about Processing, but it's silly to chat in comments about general purpose computer programming...)
It sounds like you need to maintain "state", which is a fancy way of saying a variable where you store information about if you have done something before, and what that thing is.
First, how many states do you care about? It sounds like you have two distinct options, so if you add the initial state, this technically makes three (but for only two valid states we can ignore that for now). Ok, so your startup code (constructor or initializer, whatever is typical for Processing) will set a variable of some sort to a known start value.
How to do this is up to you. It could be a String or an int or something advanced like an enum. The idea is that this is a testable, settable, persistent chunk of data that you know the meaning of.
Every time you handle the "event" of a button being pushed you do two things:
Test the state you initialized earlier and make a decision. In the initial state you want to load "2015" data. Ok. So do that.
Change the variable holding the state so it is in the "next" state. In the 2015 state we want to change that to 2016 so we are ready for the next button event we handle.
A simple example would be to create an int called dataState or something. In setup set this to 2015. In your button handler have a switch or if statement that checks for all possible values dataState can be, and runs the appropriate code for that state. e.g., if it is set to 2015 it will do whatever you need it to do for 2015, but at the end it should set the dataState to 2016 so that the next time through it does the 2016 branch.
It is up to you what the 2016 branch does to this state. You can reset it to 2015 or continue on to 2017, if your code needs to have that functionality.
Some comments:
You'll notice that your code for processing 2015 data is almost the same as the code that processes 2016 data. This is an opportunity to use a function or method that accepts a filename and does some work based on that, and then sets the state to the "next" state.
Once you do this, then your logic in the button handler becomes a nice short and understandable set of if ... else if statements that simply call the appropriate function for that state. This makes it easy to add, say, 2017 processing. Code always grows features so it's good to plan ahead for that.
Once you get really good at this, you'll start thinking about "state models" and then before you know it you'll want to have your state managed as a class or enum with a big switch statement that drives the whole works. This is a very common pattern with embedded, event driven code that Processing supports.
keep track of your year in a variable and change it when the key is pressed. Something like this
//start off one less than first desired year
int Year=2014;
void keyPressed() {
if(key==CODED) {
if(keyCode==RIGHT) {
//increment year
Year = Year+1;
//Clamp year between 2015 and 2017
Year= Math.max(2015, Math.min(2017, Year));
String yr[]= loadStrings(Year +"data.txt");
for (int i=1; i<yr.length;i++) {
Scanner sc= new Scanner(yr[i]);
int xValue= sc.nextInt();
int yValue= sc.nextInt();
int pixelX= locX2PixX(xValue);
int pixelY= locY2PixY(yValue);
stroke(200,200,250);
point(pixelX,pixelY);
}
}
}
}

How to get Clutter.Actor via its name

I am using GJS, how do I get Clutter.Actor via its name. For example, if I wanted to get GNOME Shell's top panel, how do I get its Clutter.Actor via its name "panel"?
My research ended up somewhere along Clutter.Stage which is where Actor(s) can go be appended to, however by the way I see things, there can be multiple Stages setup so I might also have to find which Stage it is the Actor I am trying to find is at. For now I want to know how I can get an Actor via its name.
I have seen from a code; Main.layoutManager.panelBox to get the GNOME Shell's top panel, however that doesn't seem applicable to my case since it's a third party Actor I am trying to get, and the way I wish to get Actor(s) is via the name since I may be working with different third party Actor(s).
There is one way that I can get this that I know of; Main.layoutManager.panelBox.get_parent().get_children() and I can just get the specific Actor via its index, but I don't think this is the best way to approach this, considering how dynamic things are, secondly, I find this way kinda sloppy so..
I was able to get the name via Looking Glass (Alt + F2 -> lg -> picker). For now, the specific Actor I am trying to get is the DashtoDock's, just for info.
Thank you~ Hope someone can help.
Unfortunately, it seems like what you're looking for is a searchByName() function, but you'll have to implement that yourself I think. Something like (untested):
function searchByName(topActor, name) {
let children = topActor.get_children();
for (let i = 0; i < children.length; i++) {
if (child.name === name) {
return child;
} else if (child.get_n_children()) {
let result = searchByName(child, name);
if (result) {
return result;
}
}
}
return false;
};
Then call it on Main.layoutManager.uiGroup where Dash to Dock is
const Main = imports.ui.main;
let dashToDock = searchByName(Main.layoutManager.uiGroup, "dashtodockContainer");

Resources