Получение значения переменной по её СТРОКОВОМУ имени

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
kiber_punk
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 11.01.2011 (Вт) 2:23

Получение значения переменной по её СТРОКОВОМУ имени

Сообщение kiber_punk » 10.11.2016 (Чт) 20:39

Допустим в программе объявленна переменная(константа) с именем "WM_SETTEXT".
Пользователь вводит в Text1 ее имя ("WM_SETTEXT") и нажав на кнопку получает ее значение.

Код: Выделить всё
Const WM_SETTEXT = 12

Private Sub Command1_Click()
  MsgBox (GetValueOfName(Text1.Text))
End Sub

Function GetValueOfName(ByVal VarName As String)
   ' ...преобразование текста в имя существующей переменной и получение ее значения
End Function

Возможно ли такое?
Mea culpa

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение ger_kar » 10.11.2016 (Чт) 21:13

Ну если вручную сделать сопоставление строкового значения с числовым (только для констант)
If VarName = "WM_SETTEXT" Then GetValueOfName = WM_SETTEXT.
Как вариант сделать один из проектов ActiveX.exe, ActiveX.dll и делать объявления констант таким образом, что бы они при компиляции попадали в TLB.
И последний вариант - сделать TLB вручную со всеми объявлениями, тогда можно эту TLB подключать к любому проекту, при одном условии, TLB должна быть доступна в рантайме и распространяться вместе с приложением или намертво вшита в исполняемый файл (exe).
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение Хакер » 11.11.2016 (Пт) 0:36

ger_kar писал(а):If VarName = "WM_SETTEXT" Then GetValueOfName = WM_SETTEXT.

Ну, лучше уж словарь, чем тупая последовательность If-ов.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение ger_kar » 11.11.2016 (Пт) 6:01

Хакер писал(а):Ну, лучше уж словарь, чем тупая последовательность If-ов.
Ну это смотря сколько значений, если несколько штук, то можно If или Select Case обойтись. А так вариантов реализации куда как больше. Можно даже базу данных заюзать. Словарь конечно хорошо, но его данные надо где то хранить, потом, перед использованием его инициализировать. А база в этом отношении гораздо удобнее.
Бороться и искать, найти и перепрятать

kiber_punk
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 11.01.2011 (Вт) 2:23

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение kiber_punk » 11.11.2016 (Пт) 8:53

Чтож, значит не судьба. Придётся многаписать.
Проблема в том что этих констант много, и пихать их сначала в чекбокс, а затем ещё и в код будет трудозатратно и рутинно.
А текстовое имя константы тоже никак нельзя получить?

..Хотя наверно проще будет сразу в чекбокс добавлять строки "WM_SETTEXT = 12", а затем парсить, отделять мух от котлет.
Mea culpa

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение Хакер » 11.11.2016 (Пт) 9:59

kiber_punk писал(а):А текстовое имя константы тоже никак нельзя получить?

Сказали же, что достаточно один раз поместить все константы в TLB.

И вообще. Используются ли «большой набор констант», о котором идёт речь, во время компиляции, или же только во время работы?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kiber_punk
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 11.01.2011 (Вт) 2:23

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение kiber_punk » 11.11.2016 (Пт) 13:55

Сказали же, что достаточно один раз поместить все константы в TLB.

Да,.но это не годится. TLB писать не умею.
Используются ли «большой набор констант», о котором идёт речь, во время компиляции, или же только во время работы?

При компиляции нет, но во время исполнения любая может быть использована.
"Генератор кастомных сообщений", для опытов.
Mea culpa

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение Хакер » 11.11.2016 (Пт) 16:24

kiber_punk писал(а):ри компиляции нет, но во время исполнения любая может быть использована.

Тогда чем не устраивает обычный словарь?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

kiber_punk
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 11.01.2011 (Вт) 2:23

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение kiber_punk » 11.11.2016 (Пт) 18:18

Хакер писал(а):Тогда чем не устраивает обычный словарь?

В принципе устраивает. Но проще
..сразу в чекбокс добавлять строки "WM_SETTEXT = 12", а затем парсить, отделять мух от котлет.
,поскольку не надо будет дублировать строки (чекбокс+словарь).

Просто решил поинтересоватьсься возможно-ли провести трюк, обозначенный в заголовке (по аналогии с вызовом метода по имени).
Mea culpa

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение Хакер » 11.11.2016 (Пт) 18:29

kiber_punk писал(а):,поскольку не надо будет дублировать строки (чекбокс+словарь).

Глупо и дичайше криво.

Почему бы числовое значение не засунуть в свойство Tag хотя бы? Почему бы действительно не отказаться от дублирования, применить словарь и не создавать набор чекбоксов по словарю?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение ger_kar » 11.11.2016 (Пт) 18:30

kiber_punk писал(а):Просто решил поинтересоватьсься возможно-ли провести трюк, обозначенный в заголовке (по аналогии с вызовом метода по имени).
По аналогии как раз можно. А аналогия тут такая. Что-бы вызвать нужный метод по имени, как раз и используется библиотека типов (TLB). Поэтому если поместить константы в такую библиотеку, то их точно так же как и методы можно будет найти по имени. В самом исполняемом файле никаких наименований не содержится. Названия есть только в исходниках, для их удобоваримого восприятия. И далее в процессе компиляции все константы заменяются на значения и на этом все. Если не юзать TLB, значит все равно придется юзать другое хранилище, без этого не обойтись.
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение ger_kar » 11.11.2016 (Пт) 19:10

kiber_punk писал(а):Да,.но это не годится. TLB писать не умею.
Этому можно достаточно быстро научится. Я по началу тоже сторонился, пока не взял себя в руки :). А взяв себя в руки, спокойно и без страха достаточно быстро все изучил. И оказалась сия наука не такой уж и мудреной. В языке описания библиотек достаточно много всяких премудростей, но для описания констант нужны минимальные знания. Вот код для твоей первой библиотеки типов.
Код: Выделить всё
//
// Это моя первая библиотека для доступа к константам по имени
//
// Строки компиляции:
// MIDL /win32 MyConstants.idl /tlb MyConstants.tlb
// или
// mktyplib MyConstants.idl
//

[
  uuid(F257AAA9-00EB-4C7A-A8F9-E13ACD6499C2), /* Это уникальный идентификатор моей TLB */
  version(0.1),
  helpstring("Это пояснение будет доступно в Object Browser")
]

library MyConstants
{
   [
   dllname("<no entry points>"),
   ]
   module Constants
   {
      const long WM_NULL = 0;
        const long WM_CREATE = 1;
        const long WM_DESTROY = 2;
        const long WM_MOVE = 3;
        const long WM_SIZE = 5;
        const long WM_ACTIVATE = 6;
        const long WA_INACTIVE = 0;
        const long WA_ACTIVE = 1;
        const long WA_CLICKACTIVE = 2;
        const long WM_SETFOCUS = 7;
        const long WM_KILLFOCUS = 8;
        const long WM_ENABLE = 10;
        const long WM_SETREDRAW = 11;
        const long WM_SETTEXT = 12;
        const long WM_GETTEXT = 13;
        const long WM_GETTEXTLENGTH = 14;
        const long WM_PAINT = 15;
        const long WM_CLOSE = 16;
        const long WM_QUERYENDSESSION = 17;
        const long WM_QUIT = 18;
        const long WM_QUERYOPEN = 19;
        const long WM_ERASEBKGND = 20;
        const long WM_SYSCOLORCHANGE = 21;
        const long WM_ENDSESSION = 22;
        const long WM_SHOWWINDOW = 24;
        const long WM_WININICHANGE = 26;
        const long WM_DEVMODECHANGE = 27;
        const long WM_ACTIVATEAPP = 28;
        const long WM_FONTCHANGE = 29;
        const long WM_TIMECHANGE = 30;
        const long WM_CANCELMODE = 31;
        const long WM_SETCURSOR = 32;
        const long WM_MOUSEACTIVATE = 33;
        const long WM_CHILDACTIVATE = 34;
        const long WM_QUEUESYNC = 35;
        const long WM_GETMINMAXINFO = 36;
        const long WM_PAINTICON = 38;
        const long WM_ICONERASEBKGND = 39;
        const long WM_NEXTDLGCTL = 40;
        const long WM_SPOOLERSTATUS = 42;
        const long WM_DRAWITEM = 43;
        const long WM_MEASUREITEM = 44;
        const long WM_DELETEITEM = 45;
        const long WM_VKEYTOITEM = 46;
        const long WM_CHARTOITEM = 47;
        const long WM_SETFONT = 48;
        const long WM_GETFONT = 49;
        const long WM_SETHOTKEY = 50;
        const long WM_GETHOTKEY = 51;
        const long WM_QUERYDRAGICON = 55;
        const long WM_COMPAREITEM = 57;
        const long WM_COMPACTING = 65;
        const long WM_OTHERWINDOWCREATED = 66;
        const long WM_OTHERWINDOWDESTROYED = 67;
        const long WM_COMMNOTIFY = 68;
        const long WM_WINDOWPOSCHANGING = 70;
        const long WM_WINDOWPOSCHANGED = 71;
        const long WM_POWER = 72;
      const long WM_COPYDATA = 74;
        const long WM_CANCELJOURNAL = 75;
        const long WM_NCCREATE = 129;
        const long WM_NCDESTROY = 130;
        const long WM_NCCALCSIZE = 131;
        const long WM_NCHITTEST = 132;
        const long WM_NCPAINT = 133;
        const long WM_NCACTIVATE = 134;
        const long WM_GETDLGCODE = 135;
        const long WM_NCMOUSEMOVE = 160;
        const long WM_NCLBUTTONDOWN = 161;
        const long WM_NCLBUTTONUP = 162;
        const long WM_NCLBUTTONDBLCLK = 163;
        const long WM_NCRBUTTONDOWN = 164;
        const long WM_NCRBUTTONUP = 165;
        const long WM_NCRBUTTONDBLCLK = 166;
        const long WM_NCMBUTTONDOWN = 167;
        const long WM_NCMBUTTONUP = 168;
        const long WM_NCMBUTTONDBLCLK = 169;
        const long WM_KEYFIRST = 256;
        const long WM_KEYDOWN = 256;
        const long WM_KEYUP = 257;
        const long WM_CHAR = 258;
        const long WM_DEADCHAR = 259;
        const long WM_SYSKEYDOWN = 260;
        const long WM_SYSKEYUP = 261;
        const long WM_SYSCHAR = 262;
        const long WM_SYSDEADCHAR = 263;
        const long WM_KEYLAST = 264;
        const long WM_INITDIALOG = 272;
        const long WM_COMMAND = 273;
        const long WM_SYSCOMMAND = 274;
        const long WM_TIMER = 275;
        const long WM_HSCROLL = 276;
        const long WM_VSCROLL = 277;
        const long WM_INITMENU = 278;
        const long WM_INITMENUPOPUP = 279;
        const long WM_MENUSELECT = 287;
        const long WM_MENUCHAR = 288;
        const long WM_ENTERIDLE = 289;
        const long WM_CTLCOLORMSGBOX = 306;
        const long WM_CTLCOLOREDIT = 307;
        const long WM_CTLCOLORLISTBOX = 308;
        const long WM_CTLCOLORBTN = 309;
        const long WM_CTLCOLORDLG = 310;
        const long WM_CTLCOLORSCROLLBAR = 311;
        const long WM_CTLCOLORSTATIC = 312;
        const long WM_MOUSEFIRST = 512;
        const long WM_MOUSEMOVE = 512;
        const long WM_LBUTTONDOWN = 513;
        const long WM_LBUTTONUP = 514;
        const long WM_LBUTTONDBLCLK = 515;
        const long WM_RBUTTONDOWN = 516;
        const long WM_RBUTTONUP = 517;
        const long WM_RBUTTONDBLCLK = 518;
        const long WM_MBUTTONDOWN = 519;
        const long WM_MBUTTONUP = 520;
        const long WM_MBUTTONDBLCLK = 521;
        const long WM_MOUSELAST = 521;
        const long WM_PARENTNOTIFY = 528;
        const long WM_ENTERMENULOOP = 529;
        const long WM_EXITMENULOOP = 530;
        const long WM_MDICREATE = 544;
        const long WM_MDIDESTROY = 545;
        const long WM_MDIACTIVATE = 546;
        const long WM_MDIRESTORE = 547;
        const long WM_MDINEXT = 548;
        const long WM_MDIMAXIMIZE = 549;
        const long WM_MDITILE = 550;
        const long WM_MDICASCADE = 551;
        const long WM_MDIICONARRANGE = 552;
        const long WM_MDIGETACTIVE = 553;
        const long WM_MDISETMENU = 560;
        const long WM_DROPFILES = 563;
        const long WM_MDIREFRESHMENU = 564;
        const long WM_CUT = 768;
        const long WM_COPY = 769;
        const long WM_PASTE = 770;
        const long WM_CLEAR = 771;
        const long WM_UNDO = 772;
        const long WM_RENDERFORMAT = 773;
        const long WM_RENDERALLFORMATS = 774;
        const long WM_DESTROYCLIPBOARD = 775;
        const long WM_DRAWCLIPBOARD = 776;
        const long WM_PAINTCLIPBOARD = 777;
        const long WM_VSCROLLCLIPBOARD = 778;
        const long WM_SIZECLIPBOARD = 779;
        const long WM_ASKCBFORMATNAME = 780;
        const long WM_CHANGECBCHAIN = 781;
        const long WM_HSCROLLCLIPBOARD = 782;
        const long WM_QUERYNEWPALETTE = 783;
        const long WM_PALETTEISCHANGING = 784;
        const long WM_PALETTECHANGED = 785;
        const long WM_HOTKEY = 786;
        const long WM_PENWINFIRST = 896;
        const long WM_PENWINLAST = 911;
        const long WM_USER = 1024;
   }
}
Возьми Notepad++ и создай в нем файл MyConstants.idl, скопируй приведенный код и сохрани.
Далее установи плагин NppExec, если он еще не установлен. После установки на панели инструментов будет доступна кнопка 'Show Console Dialog', которой можно включать/выключать отображение консоли. Вставляй туда строку для компиляции (одну их двух приведенных). Нажимаешь Enter и Вуаля! Твоя первая TLB готова. Подключай к VB6 и смотри на результат. Чтобы было удобно работать с IDL, можно сделать подсветку синтаксис. Вот его описание. Достаточно его импортировать в Notepad++
IDL.rar
(1.01 Кб) Скачиваний: 163
Бороться и искать, найти и перепрятать

kiber_punk
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 11.01.2011 (Вт) 2:23

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение kiber_punk » 11.11.2016 (Пт) 22:41

kiber_punk писал(а):,поскольку не надо будет дублировать строки (чекбокс+словарь).

ОЙ БЛИН! Чего я понаписал... Я имел ввиду ComboBox.

Хакер писал(а):Глупо и дичайше криво.

Согласен, гротеск. :lol:
Ну могли бы меня поправить, очевидно ведь, что для выбора сообщения подходит ComboBox, а никакой не checkbox.

Придумал. Можно организовать так: заполняем combobox именами сообщений со значениями соответствующими порядковому номеру итема.
В итоге имеем зависимую пару: (Combo1.List(Combo1.ListIndex) и Combo1.ListIndex ). Индексация, как и сообщения WM_, начинается с нуля.

p.s. прошу прощение за вызванное недоумение, - 2-ое суток без сна.
Mea culpa

kiber_punk
Новичок
Новичок
 
Сообщения: 41
Зарегистрирован: 11.01.2011 (Вт) 2:23

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение kiber_punk » 11.11.2016 (Пт) 23:27

ger_kar писал(а):Возьми Notepad++ и создай в нем файл MyConstants.idl, скопируй приведенный код и сохрани.Далее установи плагин NppExec, если он еще не установлен. После установки на панели инструментов будет доступна кнопка 'Show Console Dialog', которой можно включать/выключать отображение консоли. Вставляй туда строку для компиляции (одну их двух приведенных). Нажимаешь Enter и Вуаля! Твоя первая TLB готова. Подключай к VB6 и смотри на результат. Чтобы было удобно работать с IDL, можно сделать подсветку синтаксис. Вот его описание. Достаточно его импортировать в Notepad++

Премного благодарен! Разбираюсь...
А как импортировать файл подсветки в Npp?
Он у меня лежит в programfiles ещё наверно с позапрошлой инсталляции винды, но так им почти и не пользовался - привык к аскетичному и удобному Notepad2, 9 лет на нём сижу.

ger_kar писал(а): Что-бы вызвать нужный метод по имени, как раз и используется библиотека типов (TLB).

Так то я имел ввиду CallByName. :)
Mea culpa

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение The trick » 11.11.2016 (Пт) 23:54

ger_kar писал(а):Что-бы вызвать нужный метод по имени, как раз и используется библиотека типов (TLB).

Немного не так. Чтобы вызвать метод по имени TLB не нужна, а нужна поддержка IDispatch. К примеру после компиляции стандартные VB классы также позволяют вызывать свои методы по имени, хотя никакой TLB нет.
UA6527P

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Получение значения переменной по её СТРОКОВОМУ имени

Сообщение ger_kar » 12.11.2016 (Сб) 6:34

kiber_punk писал(а):А как импортировать файл подсветки в Npp?
Открываешь Notepad++ (у меня версия 6.8.5). И далее меню 'Синтаксисы' и в самом низу пункт 'Задать свой синтаксис', а там есть пару кнопочек 'Импорт', 'Экспорт'. Нажимаешь 'Импорт' и далее указываешь на файл. В том же окне можно создать свой синтаксис или подправить этот. Причем раскраску можно настроить достаточно кастомно, чего например нельзя сделать в Visual Studio.
Бороться и искать, найти и перепрятать


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16

    TopList