Рейтинг:
2
Richard MacCutchan
У меня была похожая проблема с simple Messagebox
вызовы, когда обработчик WM_PAINT не вызывает BeginPaint
/ EndPaint
последовательность. Вам может понравиться, чтобы проверить, если это возможно.
[редактировать]
// CPP implementation file
void CUserPromptDlg::GetDisplayPrompt(WCHAR *pUserPrompt)
{
wcscpy(pUserPrompt, L"Test message");
}
void CUserPromptDlg::TestFunc1()
{
GetDisplayPrompt(m_UserPrompt);
AfxMessageBox(m_UserPrompt);
SetDlgItemTextW(IDS_USER_PROMPT, m_UserPrompt);
}
Похоже, вы используете разные переменные для текста.
[/редактировать]
MickFarrell
Привет Ричард,
Я упростил код, насколько это возможно, чтобы проверить и я использую только базового класса cdialog без обработки сообщения WM_PAINT сообщение. Тот же код работает нормально, но не отображает текст при запуске в режиме администратора?
MickFarrell
Привет Ричард,
Я упростил код, насколько это возможно, чтобы проверить и я использую только базового класса cdialog без обработки сообщения WM_PAINT сообщение. Тот же код работает нормально, но не отображает текст при запуске в режиме администратора?
Richard MacCutchan
Смотрите мое обновленное решение.
MickFarrell
Привет, Ричард, один из них-указатель на массив WCHAR. m_UserPrompt объявляется в заголовочном файле.
Решение 1: если я переместил m_UserPrompt из заголовочного файла и объявил его в функции класса TestFunc1() как локальную переменную, то он работает нормально.
Решение 2: Если я скопирую содержимое m_UserPrompt в строку CString, она будет работать нормально.
Это меня совершенно озадачило?? Я убежден, что проблема связана с юникодом, но я не могу понять ее?
Richard MacCutchan
Извините, но здесь слишком много деталей, которые мы не можем увидеть. Если вам нужно переместить что-то из заголовка в файл реализации, чтобы заставить его работать, то ваше определение класса должно быть неверным. Вам нужно пройти через весь ваш код строка за строкой, чтобы убедиться, что он завершен, и что вы не ошиблись в чем-то.
MickFarrell
Привет, Ричард, Что касается вашего предыдущего решения, то чего же не хватало? Вы сказали: "Вы, кажется, используете разные переменные для текста", но это есть в коде, вызывающем функцию для установки текста?
Проблема в заголовочном файле не приведет к тому, что текст будет работать только в режиме администратора. Запуск в режиме администратора-это единственный способ "я" воспроизвести проблему, для некоторых пользователей это просто происходит, когда они запускают ее нормально
Я действительно ценю ваше время, вклад и предложения, и я действительно считаю, что проблема глубже, чем небольшой образец кода, который я предоставил, но я надеюсь, что кто-то, возможно, столкнулся с чем-то подобным в прошлом и мог бы указать мне в другом направлении. :-)
Richard MacCutchan
Извините, я неправильно прочитал код. Однако где же декларация о том, что m_UserPrompt
?
MickFarrell
Привет Ричард,
Он объявлен в заголовочном файле. Я действительно включил его в свой первоначальный пост.
// Объявлено в заголовочном файле
Тип данных wchar m_UserPrompt[128];
Richard MacCutchan
Извините, но я все больше запутываюсь. Ваш первоначальный вопрос гласит, что SetWindowText
иногда это не работает. Ваш пример использует SetDlgItemTextW
а это не совсем одно и то же. Кроме того, вы показали только части своего кода. Я думаю, что вам нужно начать снова с нового вопроса, который показывает полное определение вашего класса (будь то окно или диалог) и те части реализации, которые действительно вызывают проблему.
Наконец, вы должны знать, что SetDlgItemTextW
должны вернуться false
если это не удается, то в этот момент вам нужно позвонить GetLastError
чтобы выяснить почему. Я не говорю, что это то, что происходит, но это нужно проверить, учитывая вашу проблему.
MickFarrell
Это программа unicode, поэтому SetWindowText-это SetWindowTextW. SetWindowText (SetWindowTextW или SetWindowTextA) не возвращает значения. Вы путаете win32 api ::SetWindowText (::SetWindowTextW или ::SetWindowTextA), который возвращает true или false.
Вы дали мне идею, я попробую вызвать версию win32 и посмотреть, что она возвращает? спасибо
Richard MacCutchan
Извините, я не пользовался MFC уже много лет и предполагал (глупо), что они сделают то же самое. Я также отметил комментарий Стивеба выше, о идентификаторе, который вы используете в своем звонке. Вы уверены в этом IDS_USER_PROMPT
является ли допустимым идентификатор элемента управления диалогового окна?
MickFarrell
Привет, Ричард, я проверил, чтобы убедиться, что IDS_USER_PROMPT id уникален, и я даже добавил новое поле редактирования в диалоговое окно для проверки, и текст по-прежнему остается пустым в новом поле редактирования.
Я действительно пытался использовать ::SetWindowText и ::SetWindowTextW (::SetWindowTextA не будет компилироваться как проект UNICODE), и они оба возвращают true, даже если они не отображают текст.
У меня есть несколько тестировщиков, которые проводят обширное тестирование на Azure, и мы действительно нашли кое-что очень интересное.
Tester1 входит в Azure с помощью учетной записи Пользователя Azure "AzureTest1", и текст отсутствует.
Tester2 входит в ту же учетную запись Azure "AzureTest1", и для него появляется текст.
Tester1 использовал свой второй компьютер для входа в Azure с помощью учетной записи Azure "AzureTest1", и текст появляется.
Похоже, это как-то связано с настройками на локальном компьютере, которые были переданы в учетную запись Azure при входе в систему? Они проверяют местные и региональные настройки, чтобы увидеть, если они могут сузить его
Еще раз спасибо Ричарду за ваше время и вклад, всегда очень хорошо получить какие-то другие идеи.
Richard MacCutchan
"проверьте уникальность идентификатора IDS_USER_PROMPT"
Нас больше беспокоило, был ли это на самом деле идентификатор элемента управления или идентификатор строки ресурса.
MickFarrell
Да, это идентификатор фактического элемента управления редактированием, а не идентификатор строки ресурса.
Richard MacCutchan
Я был почти уверен, что так и должно быть, иначе это, вероятно, никогда бы не сработало. Но в подобной ситуации стоит проверить все и вся.
MickFarrell
Я согласен, я бы лучше перепроверил, чем предположил. Мы собираемся вернуться к предыдущему SDK, когда проблема отсутствовала, и запустить некоторое тестирование.
Весь проект состоит из более чем 1 миллиона строк кода со смесью c, c++, clr, c#, .net, ASP.net и есть только около 10 мест, где это происходит, и это происходит только при очень странных условиях, которые мы еще не определили.
У меня есть обходной путь, но я не хочу его реализовывать, если нам это действительно не нужно.
Рейтинг:
1
steveb
Используют ли ваши другие 15% пользователей конфигурацию компьютерного языка, установленную в EN(US)?
MickFarrell
Привет,
Я проверю у нескольких пользователей, есть ли у них разные языковые настройки на своих компьютерах.
Если это проблема с языковыми настройками, то почему это происходит со мной, когда я работаю в режиме администратора, но не тогда, когда я этого не делаю?
MickFarrell
Я проверил 4 пользователя, и все они имеют свои языковые и региональные настройки, установленные на EN(US). У одного из этих пользователей есть проблема с дисплеем
steveb
Обычно он просто отображает мусорные символы, если вы помещаете коды en(us) на кириллицу или японский язык. Кроме того, поскольку вы помещаете строку, по тому, как она выглядит, в статический текстовый элемент управления, убедитесь, что она достаточно широка. Насколько я помню, когда статический текст не помещается в поле, он остается пустым. В отличие от редактирования текстового поля.
И самое главное: вызовите UpdateData(FALSE) после того, как ваш m_UserPrompt привязан к обновлениям подпрограмм DDX_
MickFarrell
Привет, Стив, m_UserPrompt не привязан ни к одному DDX, это просто массив WCHAR с большим количеством места. Текстовое поле в диалоговом окне имеет достаточно места и отображает текст префектно, когда он не запускается от имени администратора.
steveb
Хорошо. Я не являюсь администратором на своей машине. Я только что создал приложение на основе диалогового окна и использовал именно ваш код (я вызвал TestFunc1() из OnInitDialog). И это прекрасно работает независимо от того, бежал ли я как администратор или обычный пользователь. В вашем коде не хватает чего-то еще. Не могу сказать, что именно.
Кстати, поскольку вы используете MFC, вы можете использовать CString вместо WCHAR[128] и DDX_ привязать его к элементу управления. Вызовите UpdateData(FALSE) после изменения значения CString. Если вы строите UNICODE CString, то он становится CStringW.
Также я заметил следующее: Ваш идентификатор элемента управления-IDS_USER_PROMPT. Это, может быть, ничего. Но мастер приложений MSVC использует префикс IDS_ для строк ресурсов и префикс IDC_ для элементов управления. Дважды проверьте, что ваш IDS_USER_PROMPT является не "ресурсом Строковой таблицы", а фактическим идентификатором элемента управления
MickFarrell
Все хорошие моменты Стив, и да, по умолчанию это IDC_ я попытался добавить новый элемент управления редактированием и оставил его в default define IDC_EDIT, и даже новый элемент управления редактированием не работает. Я почти уверен, что ваше предложение сработает, если я использую следующий код (добавил CString), он работает 100% времени для всех пользователей:
void CUserPromptDlg::TestFunc1()
{
GetDisplayPrompt(m_UserPrompt);
Однако темп = m_UserPrompt
SetDlgItemTextW(IDS_USER_PROMPT, temp);
}
Я удалил AfxMessageBox(m_UserPrompt), так как это только для тестирования, оно не имеет никакого влияния.
Я думаю, что вы, возможно, что-то напутали с вашим предыдущим вопросом о языке и региональных настройках. Мы создали несколько новых тестовых учетных записей в Azure для некоторых тестировщиков.
Tester1 входит в Azure с помощью учетной записи Пользователя Azure "AzureTest1", и текст отсутствует.
Tester2 входит в ту же учетную запись Azure "AzureTest1", и для него появляется текст.
Tester1 использовал свой второй компьютер для входа в Azure с помощью учетной записи Azure "AzureTest1", и текст появляется.
Похоже, это как-то связано с настройками на локальном компьютере, которые были переданы в учетную запись Azure при входе в систему? Они проверяют местные и региональные настройки, чтобы увидеть, если они могут сузить его
Спасибо Вам за помощь и предложения, Стив!