Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/40: Рейтинг темы: голосов - 40, средняя оценка - 4.78
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1

Сохранение/чтение/работа с файлами Excel без вызова СОМ (альтернативные методы)

11.05.2017, 09:35. Показов 7766. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, коллеги!
Столкнулся с такой проблемой: в проекте Windows Forms реализовал сохранение в Excel файл (в два формата) таким образом
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
58
59
60
61
62
63
using Excel = Microsoft.Office.Interop.Excel;
 
namespace KKM_ProgBase_Utility
{
    public partial class fm_Main : Form
    {
        private Excel.Application ExcelApp;
        private Excel.Range excelcells;
 
        public fm_Main()
        {
            InitializeComponent();
        }
        
        private void mi_SaveToExcel_Click(object sender, EventArgs e)
        {//Сохранение в файлы Excel
            int i, j;
            saveTags.Title = "Экспорт в файл Excel";
            saveTags.Filter = "Файл Excel (*.xls) | *.xls |Файл Excel (*.csv) |*.csv";
 
            if (saveTags.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    Excel.Application ExcelApp = new Excel.Application();
                    Excel.Workbook workbook = ExcelApp.Workbooks.Add(Type.Missing);
                    Excel.Worksheet worksheet = workbook.ActiveSheet;
                    //Заголовок таблицы
                    for (j = 0; j < ProgTable.ColumnCount; j++)
                        ExcelApp.Cells[1, j + 1] = ProgTable.Columns[j].HeaderText;
                    //Данные
                    for (i = 0; i < ProgTable.Rows.Count; i++)
                    {
                        for (j = 0; j < ProgTable.ColumnCount; j++)
                        {
                            ExcelApp.Cells[i + 2, j + 1] = ProgTable.Rows[i].Cells[j].Value;
                        }
                    }
                    //////
                    ExcelApp.AlertBeforeOverwriting = false;
                    ExcelApp.DisplayAlerts = false; //Не запрашивать сохранение
                    //сохранение в .xls
                    if (saveTags.FilterIndex == 1)
                        ExcelApp.DefaultSaveFormat = Excel.XlFileFormat.xlExcel9795;
                    //сохранение в .csv
                    if (saveTags.FilterIndex == 2)
                        ExcelApp.DefaultSaveFormat = Excel.XlFileFormat.xlCSV;
                    //Установка типов данных и формат ячеек
                    excelcells = (Excel.Range)worksheet.Columns["C", Type.Missing];
                    excelcells.NumberFormat = "#####0";
                    //Cохранение файла
                    workbook.SaveAs(saveTags.FileName, ExcelApp.DefaultSaveFormat);
                    ExcelApp.Quit();
                }
                catch (Exception ex)
                {
                    //Обработка сбоя
                    ExcelApp.Quit();
                }
            }
        }
    }
}
Если на ПК установлен MS Office то этот код работает и всё хорошо сохраняет... Но! Есть такой нюанс: пробовал сохранить в Ексель-файл на компе, где Microsoft Office не установлен, либо стоит альтернативный офис типа Либры или OpenOffice... И такая конструкция уже не срабатывает!(( Выдает ошибки, что типа COM не зарегистрирован в системе и всё такое...
Отсюда у меня вопрос: как можно реализовать сохранение/открытие в/из файлов Ексель на форму программы, без вызова СОМ ну или каким-то образом, что бы привязок к Меклкософтовскому офису на ПК не было?
Заранее спасибо за помощь!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.05.2017, 09:35
Ответы с готовыми решениями:

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

Работа с excel: Открытие, чтение, запись, сохранение книги
Доброго времени суток. Приведите, если не сложно, пару примеров работы с excel. Создание, открытие книги/страницы, сохрание в информации...

Альтернативные методы оплаты
Кто что слышал об альтернативных методах оплаты? Когда они наконец-то сделают что-то, кроме чека? Ведь обещали сделать до нового года?

17
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
11.05.2017, 09:39
OpenXml. Можно начать с этого
0
 Аватар для Павлик Морозов
138 / 137 / 42
Регистрация: 26.10.2012
Сообщений: 443
11.05.2017, 10:19
Лучший ответ Сообщение было отмечено Cha1000000 как решение

Решение

Cha1000000, можно еще проще. Уже все придумали. Бесплатная библиотека EpPlus. Неоднократно использовал ее в своих проектах. Все просто и быстро делается. Пример работы с библиотекой можно почитать здесь
1
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1
11.05.2017, 10:55  [ТС]
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
Уже все придумали. Бесплатная библиотека EpPlus.
И этот метод решает вопрос для альтернативных офисов? Если майкросовтовский на ПК не установлен, или например вообще никакого офиса нет на ПК, а сохранить из программы файл экселевского формата нужно?
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
можно еще проще.
Проще, в смысле, чем в комментарии, предложенном выше?
0
 Аватар для Павлик Морозов
138 / 137 / 42
Регистрация: 26.10.2012
Сообщений: 443
11.05.2017, 11:04
Cha1000000, эта библиотека решает проблему чтения/сохранения если вообще ничего не установлено на ПК, кроме .Net Framework. Ей не нужны никакие сторонние либо мелкософтовские решения/компоненты. Полностью самостоятельный продукт.
0
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1
11.05.2017, 11:17  [ТС]
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
эта библиотека решает проблему чтения/сохранения если вообще ничего не установлено на ПК, кроме .Net Framework. Ей не нужны никакие сторонние либо мелкософтовские решения/компоненты. Полностью самостоятельный продукт.
Отлично! Огромное спасибо! Буду читать, смотреть разбираться!
0
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1
12.05.2017, 13:55  [ТС]
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
эта библиотека решает проблему...
Добрый день! Покурил вчера инфу и примеры по, предложенной вами, библиотеке, и если я правильно понял, есть один огорчающий факт - библиотека работает только с .xlsx форматом, .xls (или на пример .csv) не поддерживает. Пока изучал материалы по данной библиотеке, нашёл, что есть ещё куча разных альтернативных библиотек на подобии этой (ну каждая, видимо, со своими особенностями). А вы можете ещё какую-то конкретную порекомендовать вместо EpPlus?
0
Эксперт .NET
 Аватар для Usaga
14136 / 9359 / 1350
Регистрация: 21.01.2016
Сообщений: 35,175
12.05.2017, 14:04
Cha1000000, XLS (как и DOC) - закрытый проприетарный формат. Сложно будет по нему инфу найти или нормальную библиотеку. CSV - открытый и очень простой формат, вы его сами сможете прочесть, без сторонних библиотек.
0
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1
12.05.2017, 14:28  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Сложно будет по нему инфу найти
А как же тогда с этими форматами работают альтернативные Китайские офисы типа Libra Office, OpenOffice, WPS Office и др.?
Цитата Сообщение от Usaga Посмотреть сообщение
вы его сами сможете прочесть, без сторонних библиотек.
Если можно немного поподробнее об этом?
0
 Аватар для Павлик Морозов
138 / 137 / 42
Регистрация: 26.10.2012
Сообщений: 443
13.05.2017, 17:49
Cha1000000, для xls другая библиотека есть. Только Вам зачем этот формат? он же древний как прах мамонта
0
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1
14.05.2017, 00:48  [ТС]
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
для xls другая библиотека есть. Только Вам зачем этот формат? он же древний как прах мамонта
Древний формат нужен потому, что разрабатываемая программа рассчитана на широкий круг потребителей. И не известно какой пакет офиса у них может быть установлен на ПК. Некоторые "динозавры", или хардкорщики ещё пользуются как ХР так офисом 2003, а тот в свою очередь, форма xlsx не поддерживает. Да, печально и досадно, что приходится позаботиться о такой совместимости, а не взять и тупо забыть про этот реликт, и смело писать сохранение/запись под xlsx формат... Но увы, что поделать... Приходится, пока "старьё" до конца не искоренится и не канет в лету, обеспечивать поддержку совместимости и всё такое...
Про библиотеку спасибо, тоже в процессе поиска сведений на ней пока остановился, разбираюсь и ищу годные примеры как по прямому импорту/экспорту из DataGreedView в xls, так и с использованием DataTable (с которым я пока дел не имел, не пользовался и не до конца пока разобрался). Буду так же признателен, если кто поделится такими примерами. Спасибо!
0
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
14.05.2017, 01:12
Цитата Сообщение от Cha1000000 Посмотреть сообщение
ищу годные примеры как по прямому импорту/экспорту из DataGreedView в xls
Используй csv. Он импортируется в любой Excel.
Цитата Сообщение от Cha1000000 Посмотреть сообщение
Некоторые "динозавры", или хардкорщики ещё пользуются как ХР так офисом 2003, а тот в свою очередь, форма xlsx не поддерживает.
Неправда. Поддерживает даже для Office 2000
0
Эксперт .NET
 Аватар для Usaga
14136 / 9359 / 1350
Регистрация: 21.01.2016
Сообщений: 35,175
14.05.2017, 06:59
Цитата Сообщение от Cha1000000 Посмотреть сообщение
Если можно немного поподробнее об этом?
Сохраните что-нибудь в данном формате, потом откройте файл в блокноте и всё сразу станет ясно...
0
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1
15.05.2017, 09:35  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
Неправда. Поддерживает даже для Office 2000
О как интересно! Не знал. Тогда можно будет подумать о том, что бы забыть об .xls и полностью перейти на xlsx... Ну и csv пожалуй буду прикручивать (на всякий случай).
0
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1
30.05.2017, 10:17  [ТС]
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
для xls другая библиотека есть
Спасибо ещё раз за информацию про библиотеку NPOI. Из грида по примеру выгрузить в эксель данные получилось, но пока только таким макаром, напрямую:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 // create xls if not exists
            if (!File.Exists("test.xls"))
            {
                wb = HSSFWorkbook.Create(InternalWorkbook.CreateWorkbook());
 
                // create sheet
                sh = (HSSFSheet)wb.CreateSheet("Лист1");
                // 3 rows, 2 columns
                for (int i = 0; i < 3; i++)
                {
                    var r = sh.CreateRow(i);
                    for (int j = 0; j < 2; j++)
                    {
                        r.CreateCell(j);
                    }
                }
                //создаёт файл и записывает туда данные
                using (var fs = new FileStream("test.xls", FileMode.Create, FileAccess.Write))
                {
                    wb.Write(fs);
                }
А вот привязать создание файла к компоненту SaveFileDialog не могу никак, обычные текстовые файлы уже много раз через него сохранял, а тут возникла проблема. Попробую пояснить её суть. Сначала код:
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
private void mi_SaveToExcel_Click(object sender, EventArgs e)
        {//Сохранение в файлы Excel
            int i, j;
 
            SaveDialog.Title = "Экспорт в файл Excel";
            SaveDialog.Filter = "Файлы Mirosoft Excel 97/2000/XP/2003(*.xls) | *.xls |Файлы Mirosoft Excel(*.csv) |*.csv";
 
            if (SaveDialog.ShowDialog() == DialogResult.OK)
            {
                if (SaveDialog.OpenFile() != null)
                {
                    //File_Name = Path.GetFileName(SaveDialog.FileName); //Имя файла 
                    File_Name = SaveDialog.FileName;   //имя файла с полным путём
                    
                    if (File.Exists(File_Name))
                    {
                        workbook = HSSFWorkbook.Create(InternalWorkbook.CreateWorkbook());
                        // create sheet
                        sheet = (HSSFSheet)workbook.CreateSheet("Лист1");
                        //Создание строк таблицы
                        for (i = 0; i < ProgTable.RowCount + 1; i++)
                        {
                            if (sheet.GetRow(i) == null)
                                sheet.CreateRow(i);
 
                            //Данные таблицы                                
                            for (j = 0; j < ProgTable.ColumnCount; j++)
                            {
                                if (sheet.GetRow(i).GetCell(j) == null)
                                    sheet.GetRow(i).CreateCell(j);
 
                                if (i == 0)//Заголовок таблицы
                                {
                                    sheet.GetRow(i).GetCell(j).SetCellValue(ProgTable.Columns[j].HeaderText);
                                }
                                else
                                    if (ProgTable[j, i - 1].Value != null)
                                    {
                                        sheet.GetRow(i).GetCell(j).SetCellValue(ProgTable[j, i - 1].Value.ToString());
                                    }
                            }
                        }
                        //Cохранение файла
                        using (var fs = new FileStream(File_Name, FileMode.Open, FileAccess.Write))
                        {
                            workbook.Write(fs);
                            MessageBox.Show("Данные успешно сохранены", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            fs.Close();
                        }
                    }
                }
            }
}
Итак, как я заметил, отлаживая пошагово, происходит следующее, при срабатывании "SaveDialog.ShowDialog() == DialogResult.OK" файл, имя которого ввели в окне SaveDialog, создаётся сразу, и как-то похоже удерживается процессом приложения, потому как дальше
C#
1
2
3
4
using (var fs = new FileStream(File_Name, FileMode.Open, FileAccess.Write))
                        {
                            workbook.Write(fs);
                        }
ничего не делает с созданным SaveDialog, файлом, пишет что он занят...

Вот такое сообщение: "Процесс не может получить доступ к файлу "D:\Documents\base.xls", так как этот файл используется другим процессом."

Может я что-то делаю не правильно и есть какой-то более верный способ сохранить в эксель данные через SaveFileDialog? Подскажите пожалуйста, а то уже как только не пробовал, ни в какую... Пробовал SaveDialog.Dispose(); вызвать после создания файла - не помогает. Может его как-то можно "освободить"?

Добавлено через 37 минут
Коллеги! Ответ из серии: "сам спросил, сам ответил".
Я уже сам успел разобраться и найти решение. И для тех, кому интересно и может быть полезным, расскажу в чём была суть.
В общем да, SaveDialog создавал и удерживал файл, и для этого понадобилось перехватить его поток и потом закрыть его, что бы освободить файл. Создал поток:
C#
1
Stream myStream;
за тем перехватил:
C#
1
if ((myStream = SaveDialog.OpenFile()) != null)
и позже закрыл его:
C#
1
myStream.Close();
В итоге получился рабочий код:
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
58
59
60
61
62
private void mi_SaveToExcel_Click(object sender, EventArgs e)
        {//Сохранение в файлы Excel
            int i, j;
 
            SaveDialog.Title = "Экспорт в файл Excel";
            SaveDialog.Filter = "Файлы Mirosoft Excel 97/2000/XP/2003(*.xls) | *.xls |Файлы Mirosoft Excel(*.csv) |*.csv";
            Stream myStream;
            if (SaveDialog.ShowDialog() == DialogResult.OK)
            {
                if ((myStream = SaveDialog.OpenFile()) != null)
                {
                    //File_Name = Path.GetFileName(SaveDialog.FileName); //Имя файла 
                    File_Name = SaveDialog.FileName;   //имя файла с полным путём
                    myStream.Close();
                    try
                    {
                        if (File.Exists(File_Name))
                        {
                            workbook = HSSFWorkbook.Create(InternalWorkbook.CreateWorkbook());
                            // create sheet
                            sheet = (HSSFSheet)workbook.CreateSheet("Лист1");
 
                            //Создание строк таблицы
                            for (i = 0; i < ProgTable.RowCount + 1; i++)
                            {
                                if (sheet.GetRow(i) == null)
                                    sheet.CreateRow(i);
 
                                //Данные таблицы                                
                                for (j = 0; j < ProgTable.ColumnCount; j++)
                                {
                                    if (sheet.GetRow(i).GetCell(j) == null)
                                        sheet.GetRow(i).CreateCell(j);
 
                                    if (i == 0)//Заголовок таблицы
                                    {
                                        sheet.GetRow(i).GetCell(j).SetCellValue(ProgTable.Columns[j].HeaderText);
                                    }
                                    else
                                        if (ProgTable[j, i - 1].Value != null)
                                        {
                                            sheet.GetRow(i).GetCell(j).SetCellValue(ProgTable[j, i - 1].Value.ToString());
                                        }
                                }
                            }
                            //Cохранение файла
                            using (var fs = new FileStream(File_Name, FileMode.Open, FileAccess.Write))
                            {
                                workbook.Write(fs);
                                MessageBox.Show("Данные успешно сохранены", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                fs.Close();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        //Обработка сбоя
                        MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }            
        }
0
 Аватар для Павлик Морозов
138 / 137 / 42
Регистрация: 26.10.2012
Сообщений: 443
30.05.2017, 21:03
Cha1000000, здорово что у Вас получилось самостоятельно решить проблему) Единственное, на мой взгляд, поскольку у Вас есть уже экземпляр Stream при создании файла, то в него и пишите содержимое файла. Не вижу смысла одним потоком создавать файл, другим редактировать
0
6 / 5 / 3
Регистрация: 04.06.2015
Сообщений: 250
Записей в блоге: 1
31.05.2017, 15:12  [ТС]
Цитата Сообщение от Павлик Морозов Посмотреть сообщение
в него и пишите содержимое файла
Да, об этом я тоже думал, оставил на потом. Просто пока не рассматривал как вместо FileStream подсунуть воркбуку Stream. Вот как раз сейчас буду смотреть, а если не получится, обращусь ;-) Спасибо!

Добавлено через 3 часа 18 минут
Всё получилось! Оказывается метод .Write(...) и принимает параметр типа Stream, я просто сразу не обратил на это внимания. Вот только теперь мне интересно, а как же он тогда проглатывал переменную var fs = new FileStream(File_Name, FileMode.Open, FileAccess.Write) c типом FileStream ? Не потому ли, что она типа var и от этого может как хамелеон подгонять свой тип данных под различные "условия"?
0
0 / 0 / 0
Регистрация: 23.05.2016
Сообщений: 2
13.08.2018, 13:22
Цитата Сообщение от Cha1000000 Посмотреть сообщение
Не потому ли, что она типа var и от этого может как хамелеон подгонять свой тип данных под различные "условия"?
Совсем нет, var просто сокращает объявление.
FileStream просто дочка Stream.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.08.2018, 13:22
Помогаю со студенческими работами здесь

Чтение и сохранение информации из .xls (Excel)
Всем еще раз привет) у кого есть какие идеи, как при помощи OLE открыть файлик, оценить размерность матрицы, и радостно записать ее в...

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

Работа с файлами, чтение/работа со строкой
Доброго времени суток. Начал работать с C++ Builder 6. Есть текстовый файл .txt с различными строками, как можно производить...

Чтение стандарта C++: альтернативные подходы к изучению
Хотел прочитать стандарт, но возникло 2 проблемы: 1. Стандарт на английском который я знаю не так уж и хорошо что бы осилить весь текст ...

Работа с файлами: чтение массива
Программа работает, но выводит космические числа. В чем может быть причина? // File.cpp: определяет точку входа для консольного...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru