Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 09.10.2014
Сообщений: 13

FormatMessage работает некорректно

11.10.2014, 11:35. Показов 1580. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток.
Мне необходимо отформатировать строку, используя Windows CE FormatMessage.
Для теста использую следующий код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        [Test]
        public void Test()
        {
            String sourceMessage = "Операционная система не может запустить %1";
            StringBuilder formattedMessage = new StringBuilder();
            string[] args = new string[] {"a"};
            const uint FORMAT_MESSAGE_FROM_STRING = 0x00000400;
            IntPtr lpSource = Marshal.StringToHGlobalUni(sourceMessage);
            String res = Marshal.PtrToStringAuto(lpSource);
            uint dwChars = FormatMessage(
                    FORMAT_MESSAGE_FROM_STRING,
                    lpSource,
                    0,
                    0, 
                    formattedMessage,
                    256 * 256,
                    args);
        }
Теоретически результат форматирования должен быть записан в formattedMessage, но нормального результата я получить не могу. Я пытался использовать FormatMessage с разными сигнатурами:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        [DllImport("kernel32.dll")]
        static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
           uint dwMessageId, uint dwLanguageId, [Out] StringBuilder lpBuffer,
           uint nSize, IntPtr Arguments);
 
        // the version, the sample is built upon:
        [DllImport("Kernel32.dll", SetLastError = true)]
        static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
           uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer,
           uint nSize, IntPtr pArguments);
 
        // the parameters can also be passed as a string array:
        [DllImport("Kernel32.dll", SetLastError = true)]
        static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
           uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer,
           uint nSize, string[] Arguments);
Но нигде нормального результата не получил.
Теоретически при входящей строке:
"The operating system can not run %1"
я должен получить:
"The operating system can not run a".
Но вместо этого получаю строку со случайными значениями или пустую строку.
Подскажите, что я делаю не так?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.10.2014, 11:35
Ответы с готовыми решениями:

Не работает FormatMessage
Добрый день. Есть программа на делфи, в которой используются функции WinApi. При возникновении исключиние, я получаю ошибку исключиния...

Formatmessage
unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,...

FormatMessage - иероглифы
if ((dwRetVal = AddIPAddress(iaIPAddress,iaIPMask,ifIndex,&NTEContext, &NTEInstance)) == NO_ERROR) { printf("\tIPv4 address %s was...

3
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
11.10.2014, 22:23
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
        [StructLayout( LayoutKind.Sequential)]
        struct va_list
        {
            [MarshalAs( UnmanagedType.LPWStr )]
            public string Arg0;
            public char Arg1;
            public int Arg2;
        }
 
        [DllImport( "kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
        static extern int FormatMessage (
            uint dwFlags,
            string lpSource,
            uint dwMessageId,
            uint dwLanguageId,
            StringBuilder lpBuffer,
            int nSize,
            ref va_list vaList
            );
 
        static void Main ( )
        {
            var sb = new StringBuilder( 256 );
            var args = new va_list() {
                Arg0 = "test",
                Arg1 = 'F',
                Arg2 = 1024
            };
 
            int a = FormatMessage(
                0x00000400 | 0x00002000,
                "Formatted message:\r\n\tstring: '%1'\r\n\tint32: '%3!i!'\r\n\tchar: '%2!c!'",
                0, 0,
                sb, sb.Capacity,
                ref args );
 
            Console.WriteLine( sb.ToString() );
        }
1
0 / 0 / 0
Регистрация: 09.10.2014
Сообщений: 13
12.10.2014, 15:43  [ТС]
Спасибо за example. Но есть проблема. Параметр public int Arg2 конвертируется неправильно. У меня он выходит то 0, то 44457440.
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
12.10.2014, 19:24
alekseustace, под Win CE запускаете или просто под Win (x86 или x64)? Под Win x64 действительно есть проблема, пока не придумал как решить (на Win CE проверить возможности не будет).

Добавлено через 28 минут
Проблема с выравниваем. Есть несколько вариантов решения:
  • Использовать структуры с явным указанием смещения полей, но тогда нужно будет для каждой версии, x86 и x64, использовать свою структуру
    C#
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    
    #if X86
            [StructLayout( LayoutKind.Explicit )]
            struct va_list
            {
                [FieldOffset( 0 )]
                [MarshalAs( UnmanagedType.LPWStr )]
                public string Arg0;
                [FieldOffset( 4 /* x86 */)]
                public char Arg1;
                [FieldOffset( 8 /* x86 */)]
                public int Arg2;
            }
    #elif X64
            [StructLayout( LayoutKind.Explicit )]
            struct va_list
            {
                [FieldOffset( 0 )]
                [MarshalAs( UnmanagedType.LPWStr )]
                public string Arg0;
                [FieldOffset( 8 /* x64 */ )]
                public char Arg1;
                [FieldOffset( 16 /* x64 */)]
                public int Arg2;
            }
    #else
    #error Unsupported platform
    #endif
     
            [DllImport( "kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
            static extern int FormatMessage (
                uint dwFlags,
                string lpSource,
                uint dwMessageId,
                uint dwLanguageId,
                StringBuilder lpBuffer,
                int nSize,
                ref va_list vaList
                );
     
            static void Main ( )
            {
                var sb = new StringBuilder( 256 );
                var args = new va_list() {
                    Arg0 = "test",
                    Arg1 = 'F',
                    Arg2 = 1024
                };
     
                int a = FormatMessage(
                    0x00000400 | 0x00002000,
                    "Formatted message:\r\n\tstring: '%1'\r\n\tint32: '%3!i!'\r\n\tchar: '%2!c!'",
                    0, 0,
                    sb, sb.Capacity,
                    ref args );
     
                Console.WriteLine( sb.ToString() );
            }
    В настройках проекта для каждой конфигурации устанавливаете соответствующий символ условной компиляции (Properties -> Build -> Conditional compilation symbols).

  • Использовать массив IntPtr[]
    C#
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
            [DllImport( "kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
            static extern int FormatMessage (
                uint dwFlags,
                string lpSource,
                uint dwMessageId,
                uint dwLanguageId,
                StringBuilder lpBuffer,
                int nSize,
                IntPtr[] vaList
                );
     
            static void Main ( )
            {
                var sb = new StringBuilder( 256 );
                
                var pParamArray = new IntPtr[3];
                pParamArray[0] = Marshal.StringToHGlobalUni( "test" );
                pParamArray[1] = (IntPtr)'F';
                pParamArray[2] = (IntPtr)1024;
     
                int a = FormatMessage(
                    0x00000400 | 0x00002000,
                    "Formatted message:\r\n\tstring: '%1'\r\n\tint32: '%3!i!'\r\n\tchar: '%2!c!'",
                    0, 0,
                    sb, sb.Capacity,
                    pParamArray );
     
                Marshal.FreeHGlobal( pParamArray[0] );
                Console.WriteLine( sb.ToString() );
            }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.10.2014, 19:24
Помогаю со студенческими работами здесь

Альтернатива функции FormatMessage - Получить текст системного сообщения
Приветствую! Необходимо получить текст системного сообщения по коду. Как известно, для этого существует FormatMessage(). Однако ею не...

Некорректно работает
Здравствуйте помогите пож-та с задачкой: Сформировать вещественный массив X1(N), N≤20, элементами которого являются случайные...

Do while работает некорректно
Не могу понять почему после умножения 2ух переменных я не могу ввести хочу ли я продолжить или нет. #define _CRT_SECURE_NO_WARNINGS ...

Некорректно работает if
Здравствуйте. У меня проблема. Если я указываю такое условие: if ( (i != k) && (j != l) ) то if срабатывает не всегда, но если...

Некорректно работает таймер
Здравствуйте! Написал для себя мелкое приложение в котором есть таймер, кнопка которая его останавливает и запускает, кнопка которая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru