Показаны сообщения с ярлыком C#. Показать все сообщения
Показаны сообщения с ярлыком C#. Показать все сообщения

понедельник, 3 сентября 2012 г.

[видеоурок] C# Авторизация ВКонтакте через Api / Работа с методами VkApi

Это ещё один на этом блоге видеотуториал, желательно смотреть все два видео, так как второе является продолжением первого и начинается второе с того места, где был закончен первый.
Исходник проекта, который создан и показан в видео:

Исходник проекта, который показан:
vk_Api_groups.rar   162 KB

суббота, 1 сентября 2012 г.

[Видеоурок] C# Работа с WebBrowser

Работа с встроенным окном браузера очень сильно упрощает во многих случаях процесс отправки POST запросов, если со стороны сервера слишком запутана система обмена cookies. В Видеоуроке показано как делать авторизацию в twitter по дпнной технологии, точно также можно сделать и для контакта, и для других соц сетей.

Также показано как исполнять Javascript в данном виджете, осуществлять просмотр html загруженной страницы, стирать сохранённые cookies.

Лично мне очень часто приходилось делать авторизацию таким образом, поэтому по моему мнению этот видеоурок вполне достоин иметь место это этом блоге.

воскресенье, 22 июля 2012 г.

C# Делаем скрин выделенной области

Выглядеть это будет так:
Для начала следует сделать импорт необходимых системных библиотек, которые по неизвестной мне причине не импортируются автоматически, но лежат в одной папке со всеми библиотеками .NET фреимворка.

Как их найти, показано в таблице ниже:


Расположение Библиотеки
PresentationCore.dll
C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\PresentationCore.dll
PresentationFramework.dll
C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\PresentationFramework.dll
WindowsBase.dll
C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\WindowsBase.dll
System.Xaml.dll
C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\System.Xaml.dll
Добавлять их в проект нужно обязательно, иначе наши дальнейшие действия не имеют смысла.

Следующим шагом добавьте в проект этот класс:
ScreenFixCore.cs   19.3 KB
Данный класс будет служить конструктором, он содержит все компоненты для работы, а мы только будем вызывать из него функции и извлекать нужные значения.

Перейдём к форме, перечислю, какие компоненты будут использоваться:
В форме у меня были добавлены только эти директивы Using (удалил те, которые не использовал):

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Windows.Media.Imaging;
using System.IO;

Необходимые переменные класса Form1:
private Bitmap bmp1;

Виджеты:
Для данного примера понадобятся
pictureBox1 - контейнер для изображения
toolStripButton - обычная кнопка, но в моём случае ещё и элемент панели инструментов. Можно и без неё обойтись, разницы никакой, разве что визуальная.

Класс ScreenFixCore.cs должен обязательно находиться в проекте.

А теперь о функции, которая делает снимок.
Вот она:
        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            //Бла бла бла, лень писать на всё комментарий =)
            //Описание каждой функции можно посмотреть если в контрекстном
            //меню найти и выбрать пункт "Перейти к определению"
            System.Windows.Media.Color ColorBackScreen = System.Windows.Media.Colors.Black;
            System.Windows.Media.Brush BrushLinesRect = System.Windows.Media.Brushes.Red;
            BitmapSource bmpImage =
                ScreenFixCore.ScreenshotMaker.BeginSelectionImageFromScreen(BrushLinesRect, 1.0d, ColorBackScreen);
            System.Drawing.Bitmap bitmap;
            using (MemoryStream outStream = new MemoryStream())
            {
                BitmapEncoder enc = new BmpBitmapEncoder();
                enc.Frames.Add(BitmapFrame.Create(bmpImage));
                enc.Save(outStream);
                bitmap = new System.Drawing.Bitmap(outStream);
            }
            bmp1 = new Bitmap(bitmap);
            pictureBox1.Image = bmp1;
        }

А теперь ловим исходник, в нём функций уже больше, но статья написана на основе него и на скриншоте, который выше показана именно его работа.
ScreenShot2.rar   92.4 KB

C# Делаем скриншот всего экрана

Как всегда, выложу исходник готовой функции и описание как ей пользоваться.

Функция, которая делает нам скрин и возвращает результат в виде изображения (экземпляр класса Bitmap).

        private Bitmap TakeScreenShot(Screen currentScreen)
        {
            Bitmap bmpScreenShot = new Bitmap(currentScreen.Bounds.Width,
                                              currentScreen.Bounds.Height,
                                              System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            Graphics gScreenShot = Graphics.FromImage(bmpScreenShot);

            gScreenShot.CopyFromScreen(currentScreen.Bounds.X,
                                       currentScreen.Bounds.Y,
                                       0, 0,
                                       currentScreen.Bounds.Size,
                                       CopyPixelOperation.SourceCopy);
            return bmpScreenShot;
        }

Пример использования функции:

        private Bitmap bmp;
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            //это действие задаёт параметр расположения 
            //изображения в pictureBox1
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;

            //Делаем снимок экрана (изображение в памяти)
            Image pr = TakeScreenShot(Screen.PrimaryScreen);

            //Создание экземпляра класса Bitmap, в котом  
            //будет короткое время храниться наше изображение
            bmp = new Bitmap(pr);

            //Впихиваем изображение в pictureBox1
            pictureBox1.Image = bmp;
        }
Также выложу в качестве примера исходник, который ещё и умеет сохранять сделанный скрин:

ScreenShot.rar   53.3 KB

понедельник, 9 июля 2012 г.

C# Как узнать процесс, который блокирует доступ к файлу

Чтобы заблокировать любой файл в ОС Windows его достаточно открыть на редактирование. Если быть точнее, это можно назвать процессом записи. Если рассмотреть работу текстовых редакторов, то при работе с текстом наш файл будет открываться только в момент сохранения и тут же закрываться. Мы рассматриваем случай, когда закрытия не произошло.

Такой ход могут использовать вредоносные программы, когда один процесс держит открытыми сразу все файлы, созданные вирусом, но современные антивирусники умеют обходить такую защиту и с лёгкостью закрывают файлы, после чего удаляют, за исключением тех случаев, когда вирус повреждает программные элементы антивирусника.

Также это могут быть просто системные файлы и их охраняет системный процесс, который как правило не видно в диспетчере задач. С этим будет по сложнее.

Лично мне это понадобилось для удаления Cookies из IE, но этот способ оказался слишком сложный и я предпочёл другой (об этом с другой статье).

Использовал утилиту созданную Майкрософтом - Handle v3.46, терминальная программа в виде ексешника, легка в использовании.
В обычном виде возвращает результат такого типа:
Пример использования:

        private void GET_PROCSS(string name)
        {                                    
            ProcessStartInfo start = new ProcessStartInfo();
            Process pr = new Process();
            //handle.exe уже добавлен в проект
            pr.StartInfo.FileName = @"handle.exe";
            pr.StartInfo.Arguments = @"-a " + name;
            pr.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            pr.StartInfo.RedirectStandardOutput = true;
            pr.StartInfo.UseShellExecute = false;
            pr.Start();
            using (StreamReader reader = pr.StandardOutput)
            {
                //Удаляем лишнее (можно по своему)
                string result = (((((reader.ReadToEnd()
                    .Replace("Handle v3.46", ""))
                    .Replace("Copyright (C) 1997-2011 Mark Russinovich", ""))
                    .Replace("Sysinternals - www.sysinternals.com", ""))
                    .Replace("\r\n\r\n\r\n\r\n\r\n", ""))
                    .Replace("pid:", ""))
                    .Replace("type:", "");
                
                ///Далее делаем обработку данныз как хотим  
             }        
        }
Как и во всех случаях, даю исходник готовой программы, которая умеет много. Наглядный пример, как использовать эту небольшую утилиту.

Halter.rar   1.2 MB

суббота, 7 июля 2012 г.

[Видеоурок] C# Работа с DataGridView, сохранение данных в файл

В данном видео будет показано как работать с элементом управления DataGridView, как добавлять данные и удалять их из таблицы. Также рассматривается алгоритм сохранения таблицы данных datagridview в текстовый файл. Параллельно с этим вы увидите пример работы с диалоговыми окнами, элемента управления МЕНЮ и тд.

Сразу дам ссылку на исходник той программы, которая показана на видео:
Work_Data.rar   50.1 KB


[Видеоурок] C# Диалог открытия/закрытия файла

В данонм случает будем работать с виджетами openFileDialog и saveFileDialog. Они стандартные и их можно без труда найти на боковой панели, где и все остальные элементы управления.

Рассмотрим на примере, как этим пользоваться.
Пример сохраниения файла.

        //Диалог созранения текстового файла
        private void созранитьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Stream mystr = null;
            saveFileDialog1.RestoreDirectory = true;            
            if (saveFileDialog1.ShowDialog() == DialogResult.OK) {
                if ((mystr = saveFileDialog1.OpenFile()) != null) {
                    //Создаём класс по работе с файлом
                    StreamWriter mywr = new StreamWriter(mystr);
                    //Записываем в память значение текстового поля
                    mywr.Write(textBox1.Text);
                    //Записываем в файл
                    mywr.WriteLine();
                    //Закрываем файл (!обязательно)
                    mywr.Close();
                    mystr.Close();
                }
            }
        }


В данном примере использовалась библиотека по работе с файлами System.IO (запись/чтение), она должна быть импортирована обязательно.

Пример открытия файла:
        //Диалог открытия файла
        private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Stream mystr = null;
            openFileDialog1.RestoreDirectory = true;
            if (openFileDialog1.ShowDialog() == DialogResult.OK) {
                if ((mystr = openFileDialog1.OpenFile()) != null) {
                    StreamReader myread = new StreamReader(mystr);
                    string str = myread.ReadToEnd();
                    textBox1.Text = str;
                    mystr.Close();
                }
            }
        }

Для более наглядного примера выложу исходник простой программы, которая умеет открывать, редактировать и сохранять текстовые файлы.


SimpleTextEdit.rar   44.0 KB

Видеоурок по созданию такого текстового редактора:


среда, 4 июля 2012 г.

C# vk api Загрузка списка друзей

Выкладываю готовый исходник. Это может послужить примером работы библиотеки apicore, которая непосредственно взаимодействует с сайтом vk.com.

Первая часть статьи уже есть на этом блоге, где частично рассматривается работа с сервисом api контакта. ССЫЛКа

Здесь вы увидите пример работы именно с классом FriendsFactory.

Для работы необходимо делать импорт библиотек ApiCore и HttpDownloader.

Скачать их можно тут:
ApiCore.dll   54.0 KB
HttpDownloader.dll   11.5 KB


Исходники проекта лежат здесь:
GetFriends_VKAPI.rar   87.0 KB


Исходники функций:

        //Объявляем переменные
        private SessionInfo sessionInfo;
        private ApiManager manager;
        private bool isLoggedIn = false;
        private List<Friend> friendList;
        private FriendsFactory friendFactory;
        private Regex userIdCheck;

        public Form1()
        {
            InitializeComponent();
        }

        //Авторизация
        private void Reauth()
        {
            if (!this.isLoggedIn)
            {
                SessionManager sm = new SessionManager(1928531, Convert.ToInt32(ApiPerms.Audio | ApiPerms.ExtendedMessages | ApiPerms.ExtendedWall | ApiPerms.Friends | ApiPerms.Offers | ApiPerms.Photos | ApiPerms.Questions | ApiPerms.SendNotify | ApiPerms.SidebarLink | ApiPerms.UserNotes | ApiPerms.UserStatus | ApiPerms.Video | ApiPerms.WallPublisher | ApiPerms.Wiki));
                this.sessionInfo = sm.GetSession(SessionAuthType.WithBrowser);
                if (this.sessionInfo != null)
                {
                    this.isLoggedIn = true;
                }
            }

            if (this.isLoggedIn)
            {
                manager = new ApiManager(this.sessionInfo);
                manager.Timeout = 10000;
                this.listBox1.Enabled = true;
                this.friendFactory = new FriendsFactory(this.manager);
                this.userIdCheck = new Regex("([\\d])+$");
                this.GetFriendList();
            }
        }

        //Загрузка списка друзей и запись данных в виджет listBox
        private void GetFriendList()
        {
            try
            {
                this.listBox1.Items.Clear();
                this.friendList = this.friendFactory.Get(FriendNameCase.Nominative, null, null, null, new string[] { "uid", "first_name", "nickname", "last_name" });
                for (int i = 0; i < this.friendList.Count; i++)
                {
                    this.listBox1.Items.Add(this.friendList[i]);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Error loading friend list:\n" + e.Message);
            }
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            //Вызов функций
            this.Reauth();
            this.GetFriendList();
        }

C# webbrowser удаление Cookies IE

Стоит сразу отметить, что виждет webbrowser использует оболочку IE, что парой и объясняет кривизну работы яваскрипта в нём. Это означает, что если нам нужно проделать какую либо обработку данных кеша, куков или истории, то мы будем работать исключительно с IE и только с ним, к сожалению.

Искал в интернете долгое время, как сделать полное удаление cookies вижета webbrowser, из всего что было проверено, рабочим вариантом оказалась только эта строка:


Process.Start("cmd.exe", "/C RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 255");

Для использования необходимо делать импорт библиотеки System.Diagnosticsона стандартная и есть в системе.
Минусом является то, что постоянно будет при работе всплывать окно командной строки и если делать в первый раз эту операцию, то мы ещё и будем долго наблюдать этот процесс.

Если у вас есть другое рабочее решение, то прошу написать в коммент. 

понедельник, 2 июля 2012 г.

C# Авторизация ВКонтакте через http без API, Часть 2, Пошаговая инструкция

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

C# Реализация Get/Post запросов

Это относится к работе с сетью, без отправки и получения запросов у нас ничего через интернет работать не может.

Есть уже готовые классы в стандартных библиотеках .NET, но всё равно писать приходится много. Рассмотрим на примере как делать Get запрос (получение данных по url):

public string GET_http(string url){
            System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            System.Net.WebRequest reqGET = System.Net.WebRequest.Create(url);
            System.Net.WebResponse resp = reqGET.GetResponse();
            System.IO.Stream stream = resp.GetResponseStream();
            System.IO.StreamReader sr = new System.IO.StreamReader(stream);
            string html = sr.ReadToEnd();
            return html;
        }

Это была простая функция, которая требует для вызова url и в результате работы отдаёт нам html загруженной страницы.

Рассмотрим POST запрос. Для начала следует сказать, что этот запрос подразумевает отправку каких либо данных сначала, а потом только получение ответа. Самым частым случаем является авторизация на сайтах через http и дальнейшая работа в этом направлении.

Пример функции, которая отправляет POST запрос (отправка данных):
public string http_post(string url, string data)
        {
            var cookies = new CookieContainer();
            ServicePointManager.Expect100Continue = false;

            var request = (HttpWebRequest)WebRequest.Create(url);
            request.CookieContainer = cookies;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            using (var requestStream = request.GetRequestStream())
            using (var writer = new StreamWriter(requestStream))
            {
                writer.Write(data);
            }

            using (var responseStream = request.GetResponse().GetResponseStream())
            using (var reader = new StreamReader(responseStream))
            {
                var result = reader.ReadToEnd();
                return result;
            }
        }

В нашем случае переменная data это то, что передаётся в post запросе. Точно также как и с get, мы получаем ответ в виде html страницы. 
Чтобы лучше разобраться что это такое, покажу на примере как правильно делать вызов данной функции:
private void button1_Click(object sender, EventArgs e)
        {         
            http_post("http://m.vk.com/","email=goga@mail.ru&pass=123");  
        }

Та функция, которую я показал, не делает авторизацию на сайт контакта, результат будет отрицательным, так как для контакта совсем иная история и url для запроса должен быть другой. Но запрос будет отправлен, всё это работает.

C# Авторизация ВКонтакте через http без api

В этой статье вы увидите уже готовую функцию, которая авторизует клиента по логину и паролю и возвращает булево значение true или false в зависимости от того, прошла авторизация или нет.
В следующей статье будет рассмотрено то, как я пришёл к этому коду и как вообще делать авторизацию через http на других сайтах.

При работе будет использоваться библиотека HtmlAgilityPack для парсинга Html. Подробнее об этой библиотеке можно прочесть тут.

Авторизация проходит через мобильную версию сайта контакта, так как это проще в реализации.

Вот функция:
        public bool http_auth_vk(string login, string pass)
        {
            //*****************************
            //Получаем action_url
            //*****************************
            System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            System.Net.WebRequest reqGET = System.Net.WebRequest.Create("http://m.vk.com/");
            System.Net.WebResponse resp = reqGET.GetResponse();
            System.IO.Stream stream = resp.GetResponseStream();
            System.IO.StreamReader sr = new System.IO.StreamReader(stream);
            string s = sr.ReadToEnd();


            //*****************************
            //Парсим
            //*****************************
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(s);
            HtmlNode bodyNode = doc.DocumentNode.SelectSingleNode("//div[@class='cont']/form");
            string result1 = bodyNode.Attributes["action"].Value;

            //*****************************
            //POST запрос
            //*****************************
            var cookies = new CookieContainer();
            ServicePointManager.Expect100Continue = false;
            var request = (HttpWebRequest)WebRequest.Create(result1);
            request.CookieContainer = cookies;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            using (var requestStream = request.GetRequestStream())
            using (var writer = new StreamWriter(requestStream))
            {
                writer.Write("email=" + login + "&pass=" + pass);
            }

            using (var responseStream = request.GetResponse().GetResponseStream())
            using (var reader = new StreamReader(responseStream))
            {
                var result = reader.ReadToEnd();

                //*****************************
                //Парсим, поиск ID
                //*****************************                 
                HtmlAgilityPack.HtmlDocument doc2 = new HtmlAgilityPack.HtmlDocument();                
                doc2.LoadHtml(result);
                string result2;
                try
                {                                     
                    
                    HtmlNode bodyNode2 = doc2.DocumentNode.SelectSingleNode("//div[@class='user_wrap']/a");
                    result2 = bodyNode2.Attributes["href"].Value.Substring(3);
                    //Если ID найден, то авторизация удалась
                    return true;
                }
                catch
                {
                    //Если ID не найден, то авторизация не удалась
                    MessageBox.Show("Ошибка авторизации, проверьте правильность введённых данных.\nВозможно там капча.");
                    return false;
                }
            }
        }

Пример использования:

        private void button1_Click(object sender, EventArgs e)
        {
            string login = textBox1.Text;
            string pass = textBox2.Text;
            bool avt = http_auth_vk(login, pass);
            if (avt == true)
            {
                toolStripStatusLabel1.Text = "Авторизовались успешно";

            }
            else {
                toolStripStatusLabel1.Text = "Данные не верны, попробуйте снова";
            }
        }


Необходимо делать импорт библиотек как показано ниже:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using HtmlAgilityPack;

В своей программе я использовал виджет статусной строки statusStrip и после проверки авторизации результат появлялся там.
Вот так выглядит мой вариант:
Вот исходники:
 VK Simple.rar   155 KB
Работа через Http без использования Api может быть нужна только лишь для проверки валидности аккаунта(ов), так как все остальные действия уже делать во много раз сложнее. Разработчики контакта пожизненно борются с ботами, которые работают через http и результат реально виден. Если вы хотите программным путём работать с группами, друзьями, пабликами и тд, то делать это будет логично только используя api.
Как работать с Api контакта рассказано в этой статье.

суббота, 30 июня 2012 г.

C# Работа с математическими функциями. Библиотека Math

В классе Math определены такие стандартные математические операции, как извлечение квадратного корня, вычисление синуса, косинуса и логарифмов.

Методы перечислены в таблице ниже:


Описание
Math.Acos(double p1)
Возвращает арккосинус параметра p1 -->  p1∈[-1;1]
Math.Asin(double p1)
Возвращает арксинус параметра p1 -->  p1∈[-1;1]
Math.Atan(double p1)
Возвращает арктангенс p1
Math.Atan2(double x, double y)
Возвращает арктангенс частного x/y
Math.Ceiling(double p1)
Возвращает наименьшее целое (представленное в виде значения с плавающей точкой), которое не меньше параметра p1. Например, при p1, равном 1.02, метод Ceiling() возвратит 2.0. А при p1, равном -1.02, метод Ceiling() возвратит -1 
Math.Cos(double p1)
Возвращает косинус параметра p1
Math.Cosh(double p1)
Возвращает гиперболический косинус параметра p1
Math.Exp(double p1)
Возвращает основание натурального логарифма е, возведенное в степень p1
Math.Floor(double p1)
Возвращает наибольшее целое (представленное в виде значения с плавающей точкой), которое не больше параметра p1. Например, при p1, равном 1.02, метод Floor() возвратит 1.0. А при p1, равном -1.02, метод Floor() возвратит -2
Math.IEEERemainder(double x,double y)
Возвращает остаток от деления x/y
Math.Log(double p1)
Возвращает натуральный логарифм для параметра p1
Math.Log(double p1, double p2)
Возвращает логарифм для параметра p1 по основанию p2
Math.Log10(double p1)
Возвращает логарифм для параметра v по основанию 10
Math.Pow( double base, double exp)
Возвращает значение base, возведенное в степень exp
Math.Round(double p1)
Возвращает значение p1, округленное до ближайшего целого числа
Math.Sign(double p1)
Возвращает -1, если значение v меньше нуля, 0, если p1 равно нулю, и 1, если v больше нуля
Math.Sin(double p1)
Возвращает синус параметра p1
Math.Sinh(double p1)
Возвращает гиперболический синус параметра p1
Math.Tan(double p1)
Возвращает тангенс параметра p1
Math.Sqrt(double p1)
Возвращает квадратный корень параметра p1

Пример использования:


        private void Form1_Load(object sender, EventArgs e)
        {

            label1.Text = Math.Pow(5, 7).ToString();
        }

пятница, 29 июня 2012 г.

C# Информационное окно MessageBox

Это то, что надо знать обязательно при программировании, но не всегда в учебниках об этом упоминается.
Данное окно хорошо помогает при необходимости показать на экране промежуточное значение переменной, если нету желания добавлять новый элемент на форме.
Использоваться будет класс MessageBox который работает с типом данных string. Это означает, что если мы хотим показать на экране переменную, первоначальный формат которой int, long и др., то необходимо сделать конвертацию в текстовый формат.

Вот так выглядит простой пример использования:

        private void Form1_Load(object sender, EventArgs e)
        {
            MessageBox.Show("текст уведобмения в формате string");
        }


Пример с использованием конвертации при помощи метода ToString():  
        private void Form1_Load(object sender, EventArgs e)
        {
            double a = 11.0000;
            double b = 2;
            double c = a/b;
            MessageBox.Show(c.ToString());
        }

Если мы хотим получить результат без остатка, то можем воспользоваться методом Split().
Пример:
        private void Form1_Load(object sender, EventArgs e)
        {
            double a = 11.0000;
            double b = 2;
            double c = a/b;
            //Число -> index = 0
            MessageBox.Show("Число без остатка: "+c.ToString().Split(',')[0]);
            //Находжение остатка
            try
            {
                //если остаток есть
                //Остаток -> index = 1
                MessageBox.Show("Остаток:  " + c.ToString().Split(',')[1]);
            }
            catch {
                //если остатка нету
                MessageBox.Show("Числа "+a+" и "+b+" делятся без остатка");
            }

TROCKII БЛОГ Copyright © 2012 | Template created by Lev Trockii |