- Регистрация
- 11.05.2015
- Сообщения
- 3 785
- Благодарностей
- 1 949
- Баллы
- 113
Всем привет, в этой статье, я опишу суть как можно формы (WinForms) созданные в VisualStudio адаптировать под работу в проектах ZennoPoster.
Эти формы можно использовать как для создания своего интерфейса входных настроек, так и для любых других нужд своих проектов.
Весь процесс будет через C#. Это моя первая конкурсная статья (участие в конкурсе шаблоном, я в расчет не принимаю), и в изучении C# я только оттачиваю свои навыки поэтому прошу принять это во внимание. Если Ваш уровень выше моего, и что то можно было сделать более оптимально буду рад Вашим комментариям.
На форуме есть отличная статья про работу с WinForms, там описано как самому создавать форму с нужными компонентами, чтобы использовать ее в своем проекте ZennoPoster, но это все надо делать вручную и задавать все параметры, а это очень не удобно и занимает больше времени. Поэтому лучше создавать формы в VisualStudio и адаптировать их для использования в своих проектах, написав свой шаблон для их преобразования .
Итак, начинаем. Все формы в проектах VisualStudio записываются в три файла. В именах этих файлов содержится название формы.
Например: если форма называется FormForZenno, тогда в файле FormForZenno.cs будет код действий для этой формы при загрузке формы, нажатии на кнопки, выборе значений элементов и т.п., в файле FormForZenno.Designer.cs содержится код дизайна формы (все ее элементы и компоненты) и в файле FormForZenno.resx содержатся все значения для дизайна формы. Вот эти файлы и нужны для работы, скопируем их содержимое в переменные проекта ZennoPoster.
Перенесем код из этих файлов в строковые переменные проекта Zennoposter.
В переменной strCodeActions будет код действий из файла FormForZenno.cs
В переменной strFormDesign будет код дизайна формы из файла FormForZenno.Designer.cs
В переменной strRESX будет код с ресурсами из файла FormForZenno.resx
Шаг 1: Обработка действий
В первую очередь обработаем код действий из файла FormForZenno.cs. Для того чтобы адаптировать код нужно для всех действий при клике заменить все "_Click" на ".Click+=delegate" или для действий при загрузке формы заменить "_Load" на ".Load+=delegate".
Если в форме не используются действия (ни при загрузке формы, ни нажатия на кнопки и т.п.), этот шаг можно пропустить
Вот код этой обработки для кубика C#
После выполнения этого кода, каждый блок кода действий будет разделен комментарием уникальными символами, которые нигде в коде не могут встречаться. В данном случае, я взял символы "//@@". Такой же комментарий нужно добавить в конец переменной с кодом действий, тогда по регулярке можно будет выдергивать блок кода для нужного компонента (например кнопки) и вставлять в нужное место файла результата после обработки файлов с дизайном и ресурсами.
Работа с обработкой файла действий, завершена(к нему вернемся при сборке в итоговый файл с результатом). Переходим к обработке с файлом дизайна формы.
Шаг 2: Обработка файла с дизайном формы
При обработке файла FormForZenno.Designer.cs нужно получить названия всех компонентов, а так же сделать их инициализацию и подключение к форме. Название формы можно задать вручную (или получением из кода)
В коде с дизайном ищем все компоненты и разделяем их на Имя компонента и его Класс для правильной инициализации в коде кубика C#
так строка strInit для формы будет иметь значение "System.Windows.Forms.Form FormForZenno = new System.Windows.Forms.Form(); что создаст новую форму без ошибок.
При создании формы в VisualStudio код компонентов автоматически генерируется, о чем в файле есть метки (в аналогах VisualStudio этот код может быть другим
Между #region и #endregion код всех компонентов формы, который нужно будет обработать.
Код обработки сбора названия и классов компонентов формы в список
После выполнения этого кода получаем список компонентов формы для которых будем собирать их параметры. Список будет вида textBox1|TextBox (Название компонента и его Класса через разделитель | (вертикальная черта) )
Параметры компонентов и самой формы разделены на блоки с названием компонента в комментарии.
Параметры самой формы задаются после параметров всех компонентов.
Далее в цикле перебираем все компоненты по их именам из списка listCompName и в список listCompParam собираем все блоки с параметрами каждого компонента
Код обработки
В итоге получили список с параметрами для каждого компонента.
В цикле перебора значений для каждого параметра компонента определяем, есть ли у него действия на клик или значения в файле с ресурсами.
Действия при клике выглядят так
Если есть ресурсы (в параметре содержится resources.ApplyResources или просто resources) делаем их обработку кода из переменной strRESX (код из файла FormForZenno.resx). Если форма простая, то значения в ресурсы могут и не записываться, все значения будут в параметрах компонента и их обработка не потребуется.
Код обработки если есть действие при клике
Таким образом получили код нужного действия
Для обработки действий при загрузке формы и остальных параметров (без использования ресурсов) используем такой код обработки
Таким кодом мы вместо строки с действием вставляем сам код действия адаптированный под выполнение в ZennoPoster и комментарий проверки синтаксиса и лишних символов.
После цикла обработки всех параметров осталось все собрать в файл результатов и сохранить в файл
В итоге получаем файл с результатами и комментариями. Код из этого файла можно вставить в кубик C# и проверить работу нашей формы.
Шаг 3: Финальные правки
После переноса кода из итогового файла в кубик C# и его запуске может выдать несколько ошибок, это нормально, просто надо прочитать комментарии рядом с этими строками и внести исправления вручную.
Привожу два комментария на которые надо обратить внимание:
Просто делаете что написано в таких комментариях и все готово, форма работает.
Подробности смотрите в видео к этой статье.
В прикрепленном архиве исходные файлы, которые были использованы при написании этой статьи и файл с полученным результатом, а так же шаблон лайт версии проекта.
В статье была пропущена обработка ресурсов, на это потребуется больше времени. Это будет доступно в полной (возможно платной) версии шаблона, или код обработки ресурсов можете сделать своими силами, применяя знания на практике.
Эти формы можно использовать как для создания своего интерфейса входных настроек, так и для любых других нужд своих проектов.
Весь процесс будет через C#. Это моя первая конкурсная статья (участие в конкурсе шаблоном, я в расчет не принимаю), и в изучении C# я только оттачиваю свои навыки поэтому прошу принять это во внимание. Если Ваш уровень выше моего, и что то можно было сделать более оптимально буду рад Вашим комментариям.
На форуме есть отличная статья про работу с WinForms, там описано как самому создавать форму с нужными компонентами, чтобы использовать ее в своем проекте ZennoPoster, но это все надо делать вручную и задавать все параметры, а это очень не удобно и занимает больше времени. Поэтому лучше создавать формы в VisualStudio и адаптировать их для использования в своих проектах, написав свой шаблон для их преобразования .
Итак, начинаем. Все формы в проектах VisualStudio записываются в три файла. В именах этих файлов содержится название формы.
Например: если форма называется FormForZenno, тогда в файле FormForZenno.cs будет код действий для этой формы при загрузке формы, нажатии на кнопки, выборе значений элементов и т.п., в файле FormForZenno.Designer.cs содержится код дизайна формы (все ее элементы и компоненты) и в файле FormForZenno.resx содержатся все значения для дизайна формы. Вот эти файлы и нужны для работы, скопируем их содержимое в переменные проекта ZennoPoster.
Перенесем код из этих файлов в строковые переменные проекта Zennoposter.
В переменной strCodeActions будет код действий из файла FormForZenno.cs
В переменной strFormDesign будет код дизайна формы из файла FormForZenno.Designer.cs
В переменной strRESX будет код с ресурсами из файла FormForZenno.resx
Шаг 1: Обработка действий
В первую очередь обработаем код действий из файла FormForZenno.cs. Для того чтобы адаптировать код нужно для всех действий при клике заменить все "_Click" на ".Click+=delegate" или для действий при загрузке формы заменить "_Load" на ".Load+=delegate".
Если в форме не используются действия (ни при загрузке формы, ни нажатия на кнопки и т.п.), этот шаг можно пропустить
Вот код этой обработки для кубика C#
C#:
// Паттерн регулярки для поиска
string strPattern = @"(?<=\ ).*?_Click";
// Цикл добавления комментария перед каждым действием на клик
foreach (Match rxMatch in Regex.Matches(strCodeActions, strPattern)) {
// ищем private void и т.п. для удаления перед _Click
strPattern = @"\ .*\ ";
//= Берем первое совпадение с регуляркой
string strTempForReplace = new Regex(strPattern).Match(rxMatch.Value).Value.Trim();
// Комментарий с уникальными символами, для вставки перед кодом действия
string strHashTag= "//@@"";
//Все совпадения
strCodeActions = strCodeActions.Replace(strTempForReplace, strHashTag);
project.Variables["sourceForm"].Value = strCodeActions;
}
// Для действий при клике
strCodeActions = strCodeActions.Replace("_Click", ".Click+=delegate");
// Для действий при загрузке формы
strCodeActions = strCodeActions.Replace("_Load", ".Load+=delegate");
Работа с обработкой файла действий, завершена(к нему вернемся при сборке в итоговый файл с результатом). Переходим к обработке с файлом дизайна формы.
Шаг 2: Обработка файла с дизайном формы
При обработке файла FormForZenno.Designer.cs нужно получить названия всех компонентов, а так же сделать их инициализацию и подключение к форме. Название формы можно задать вручную (или получением из кода)
C#:
// Создаем список куда записываем результат обработки
List<string> lstResult = new List<string>();
// Название формы FormName
string strFormName = "FormForZenno";
//потом формируем строку для Инициализации формы
string strInit = String.Format("System.Windows.Forms.Form {0} = new System.Windows.Forms.Form();", strFormName);
// Записываем ее в список
lstResult.Add(strInit);
В коде с дизайном ищем все компоненты и разделяем их на Имя компонента и его Класс для правильной инициализации в коде кубика C#
так строка strInit для формы будет иметь значение "System.Windows.Forms.Form FormForZenno = new System.Windows.Forms.Form(); что создаст новую форму без ошибок.
При создании формы в VisualStudio код компонентов автоматически генерируется, о чем в файле есть метки (в аналогах VisualStudio этот код может быть другим
Между #region и #endregion код всех компонентов формы, который нужно будет обработать.
Код обработки сбора названия и классов компонентов формы в список
C#:
// Блок список компонентов в без параметров формы
strPattern = @"(?<=InitializeComponent)[\w\W]*?(?=//)";
//= Берем первое совпадение с регуляркой (все блоки с параметрами компонентов)
string strListComp = new Regex(strPattern).Match(strFormDesign).Value.Trim();
// Регулярка список компонентов в правильном порядке
strPattern = @"(?<=this\.).*?;";
// Создадим список компонентов
List<string> listCompName = new List<string>();
listCompName.Clear();
// части CompClassName и CompName
string strCompClassName = String.Empty;
string strCompName = String.Empty;
// Ищем все совпадения для сохранения в список компонентов
foreach (Match rxMatch in Regex.Matches(strListComp, strPattern)) {
// удаляем все this, если они остались
string strTemp = rxMatch.Value.Trim().Replace("this.", String.Empty);
// Разделяем на Имя компонента и Класс
string[] arrTemp = strTemp.Split('=');
if (arrTemp.Length > 1) {
// Все совпадения кладем в список
strCompName = arrTemp[0].Trim();
strCompClassName = arrTemp[1].Trim();
string strTempPattern = @"(?<=\ System\.Windows\.Forms\.).*?(?=\()";
//= Берем первое совпадение с регуляркой (все блоки с параметрами компонентов)
strCompClassName = new Regex(strTempPattern).Match(strCompClassName).Value.Trim();
if (strCompClassName != String.Empty) {
strTemp = strCompClassName + "|" + strCompName;
listCompName.Add(strTemp);
}
}
}
// Добавляем название формы для сбора ее параметров
listCompName.Add(String.Format(@"Form|{0}", strFormName));
Параметры компонентов и самой формы разделены на блоки с названием компонента в комментарии.
Параметры самой формы задаются после параметров всех компонентов.
Далее в цикле перебираем все компоненты по их именам из списка listCompName и в список listCompParam собираем все блоки с параметрами каждого компонента
Код обработки
C#:
// Регулярка Вырезаем блок с параметрами всех компонентов формы
strPattern = @"(?<=InitializeComponent)[\w\W]*(?=\#endregion)";
//= Берем первое совпадение с регуляркой (все блоки с прараметрами компонентов)
string strListParamComp = new Regex(strPattern).Match(strFormDesign).Value.Trim();
// Удаляем все this.
strListParamComp = strListParamComp.Replace("this.", String.Empty).Trim();
// Создадим список
List<string> listCompParam = new List<string>();
listCompParam.Clear();
while (listCompName.Count > 0) {
//Берем из списка ListCompName первую строку с удалением
string[] arrTemp = listCompName[0].Split('|');
listCompName.RemoveAt(0);
//Разделяем на части CompClassName и CompName
strCompClassName = arrTemp[0];
strCompName = arrTemp[1];
if (strCompClassName != "Form") {// Пропускаем формирование инициализации формы (сделали его раньше)
//формируем строки для Инициализации компонента из списка
strInit = String.Format("System.Windows.Forms.{0} {1} = new System.Windows.Forms.{0}();", strCompClassName, strCompName);
// Записываем в список
lstResult.Add(strInit);
}
// Название след. компонента
string strCompNameNext = String.Empty;
if (listCompName.Count > 0) {
//Берем из списка ListCompName первую строку с удалением
arrTemp = listCompName[0].Split('|');
//Разделяем на части CompClassNameNext и CompNameNext
//CompClassNameNext = arrTemp[0];
strCompNameNext = arrTemp[1];
} else {
// когда все названия компонентов закончились, собираем параметры для формы
strCompNameNext = String.Empty;
}
// Разделяем на блоки отдельных компонентов между strCompName и strCompNameNext
if (strCompName == strFormName){
strPattern = String.Format(@"(?<=//\ {0})[\w\W]*", strCompName);
} else {
strPattern = String.Format(@"(?<=//\ {0})[\w\W]*?(?=//\ {1})", strCompName, strCompNameNext);
}
// Вырезаем параметры компонента CompName {1} в CompNameNext {3}
string strCodeParamComp = new Regex(strPattern).Match(strListParamComp).Value.Trim();
// удаляем лишние символы // по краям
strCodeParamComp = strCodeParamComp.Replace("//", String.Empty).Trim();
// задаем временную переменную для обработки параметров
string strTemp = String.Empty;
string strParamCompName = String.Empty;
// Выбираем строку отдельного параметра компонента от начала строки до ;
strPattern = @"([\w\W]*?;)";
// Для перебора всеx параметров у этого компонента
foreach (Match rxMatch in Regex.Matches(strCodeParamComp, strPattern)) {
strTemp = rxMatch.Value.Trim();
// Код цикла перебора значений для каждого компонента (будет описан ниже)
}
}// закончили перебор всеx компонентов из списка listCompName
В цикле перебора значений для каждого параметра компонента определяем, есть ли у него действия на клик или значения в файле с ресурсами.
Действия при клике выглядят так
Если есть ресурсы (в параметре содержится resources.ApplyResources или просто resources) делаем их обработку кода из переменной strRESX (код из файла FormForZenno.resx). Если форма простая, то значения в ресурсы могут и не записываться, все значения будут в параметрах компонента и их обработка не потребуется.
Код обработки если есть действие при клике
C#:
// Регулярка выбора кода действия для компонента по разделителю strHashTag (уникальные символы которые мы задали “//@@”
strPattern = String.Format(@"{0}[\w\W]*?(?={1})", strCompName, strHashTagComment);
//= Берем первое совпадение с регуляркой (все блоки с параметрами компонентов)
string strClickAction = new Regex(strPattern).Match(strCodeActions).Value.Trim();
// Комментарий для кода в файле
//разделитель элементов списка
string strDelimiter = Environment.NewLine;
strComment = String.Format("{1}// Действие при клике для {0} {1}// Проверьте синтаксис и количество закрывающих скобок и ; {1}", strCompName, strDelimiter);
// Записываем в список
listCompParam.Add(strComment);
// Код действий при клике
strClickAction = strClickAction.Replace("DialogResult", "System.Windows.Forms.DialogResult") + ";" + strDelimiter;
// Добавляем название формы
strClickAction = strClickAction.Replace(@"Close()", String.Format(@"{0}.Close()", strFormName));
listCompParam.Add(strClickAction);
Для обработки действий при загрузке формы и остальных параметров (без использования ресурсов) используем такой код обработки
C#:
//Обработка параметров формы и остальных параметров компонентов без ресурсов записываем в список параметров
if (strCompName == strFormName) {
if (!strTemp.Contains("Layout") && !strTemp.Contains("Init")){
// Для параметров формы
if (strTemp.Contains("+=")){
// Для действий при загрузке формы
string strFormAction = new Regex(@"(?<=\().*(?=\))").Match(strTemp).Value.Trim();
strFormAction = strFormAction.Replace("_",".");
// Регулярка выбора кода действия для компонента
strPattern = String.Format(@"{0}[\w\W]*?(?={1})", strFormAction, strHashTagComment);
//= Берем первое совпадение с регуляркой (все блоки с прараметрами компонентов)
string strClickAction = new Regex(strPattern).Match(strCodeActions).Value.Trim();
// Комментарий для кода в файле
strComment = String.Format("{1}// Действие при клике для {0} {1}// Проверьте синтаксис и количество закрывающих скобок и ; {1}", strFormAction, strDelimiter);
// Код действий при клике
strClickAction = strClickAction.Replace("DialogResult", "System.Windows.Forms.DialogResult") + ";" + strDelimiter;
// Формируем нужный код
strTemp = strComment + strClickAction;
} else {
strTemp = strFormName + "." + strTemp;
}
} else if (strTemp.Contains("Init")) {
// Для остальных параметров
strTemp = "// Пропуск параметра System.ComponentModel.ISupportInitialize";
}
}
listCompParam.Add(strTemp);
После цикла обработки всех параметров осталось все собрать в файл результатов и сохранить в файл
C#:
// Переносим собранные параметры в список
lstResult.AddRange(listCompParam);
// Параметры для формы
strComment = strDelimiter + String.Format(@"// Добавьте {0}. к ResumeLayout и PerformLayout выше этого сообщения", strFormName);
lstResult.Add(strComment);
// Параметры для Диалога по умолчанию
//strComment = strDelimiter + String.Format(@"Добавьте {0}. к ResumeLayout и PerformLayout выше этого сообщения", strFormName);
//lstResult.Add(strComment);
// Параметры для формы по умолчанию
strComment = strDelimiter
+ "// Закомментируйте параметры формы по умолчанию, если они заданы в ее настройках"
+ strDelimiter
+ "// Название формы по умолчанию"
+ strDelimiter
+ String.Format(@"{0}.Text = ""Название Формы"";", strFormName)
+ strDelimiter
+ "// АвтоРазмер формы по умолчанию"
+ strDelimiter
+ String.Format(@"{0}.AutoSize = true;", strFormName)
+ strDelimiter
+ "// Местоположение формы по умолчанию"
+ strDelimiter
+ String.Format(@"{0}.Location = new System.Drawing.Point(150,300);", strFormName)
+ strDelimiter
+ "// Запуск формы по центру экрана"
+ strDelimiter
+ String.Format(@"{0}.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;", strFormName)
+ strDelimiter
+ "// Размер формы по умолчанию"
+ strDelimiter
+ String.Format(@"{0}.Size = new System.Drawing.Size(300, 180);", strFormName)
+ strDelimiter;
lstResult.Add(strComment);
// Показываем эту форму
strComment = strDelimiter
+ "// Показываем нашу форму "
+ strDelimiter
+ String.Format(@"{0}.ShowDialog();", strFormName);
lstResult.Add(strComment);
//сохраняем список в файл с заменой содержимого файла (после сбора всех данных в список)
File.WriteAllText(strFilePathReslt, String.Join(strDelimiter, lstResult));
project.SendInfoToLog(String.Format(@"Все готово. Результат в файле {0}", strFilePathReslt)
);
Шаг 3: Финальные правки
После переноса кода из итогового файла в кубик C# и его запуске может выдать несколько ошибок, это нормально, просто надо прочитать комментарии рядом с этими строками и внести исправления вручную.
Привожу два комментария на которые надо обратить внимание:
C#:
// Проверьте синтаксис и количество закрывающих скобок и ;
// Добавьте FormForZenno. к ResumeLayout и PerformLayout выше этого сообщения
Подробности смотрите в видео к этой статье.
В прикрепленном архиве исходные файлы, которые были использованы при написании этой статьи и файл с полученным результатом, а так же шаблон лайт версии проекта.
В статье была пропущена обработка ресурсов, на это потребуется больше времени. Это будет доступно в полной (возможно платной) версии шаблона, или код обработки ресурсов можете сделать своими силами, применяя знания на практике.
- Тема статьи
- Нестандартные хаки
- Номер конкурса статей
- Девятый конкурс статей
Вложения
-
52,2 КБ Просмотры: 462
Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...
Для того чтобы запустить шаблон, откройте нужную программу. Нажмите кнопку «Добавить», и выберите файл проекта, который хотите запустить.
Подробнее о том, где и как выполняется проект.
Последнее редактирование: