[.net, mc++] как рисовать?

serg-2000

когда-то в детстве я писал на MFC небольшие прожки и там рисовал с помощью DC и так далее.
но это была в 10 классе и с тех пор ничего под виндоус мне к счастью писать не приходилось - обходился текстовым интерфейсом или глютом.
сейчас поставил дотНет и сделал себе стандартный шаблон диалогового приложения.
насколько я могу понять построение программы изменилось.
внимание вопрос - как теперь рисовать, что для этого надо сделать и ипользовать?
и в общем где можно почитать о программировании под виндоуз как таковом

bastii

Так ничего принципиально и не изменилось. Только теперь сообщение WM_PAINT, как правило, обрабатывается через событие OnPaint, а вместо GDI используют GDI+, где вместо DC будет Graphics. Короче как и раньше помогают MSDN и примеры.

Dasar

> и в общем где можно почитать о программировании под виндоуз как таковом
Петцольд. Программирование для Microsoft Windows на C#

serg-2000

а в сети что-нибудь на тему есть?

serg-2000

спасибо большое димычу за помощь! принципиально я с рисованием разобрался, но теперь начинаются чудеса.
ну чем компилятору не нравится скопированный из примеров кусок:
Color newColor(255, 0, 0, 255);
Pen pen( newColor );
graphics->DrawLine(&pen, 0, 0, 200, 100);
ошибки (каждой строчке по ошибке)
1)error C2661: 'System::Drawing::Color::Color' : no overloaded function takes 4 arguments (хотя такая есть! - с тремя параметрами такая же фигня)
2) error C2262: 'pen' : cannot be destroyed
3) - последняя стрчока - error C3149: 'System::Drawing::Pen' : illegal use of managed type 'System::Drawing::Pen'; did you forget a '*'? - хотя в определении функции недвусмысленно написано что ей нужен указатель.

Dasar

Это на C++ под .Net пишешь?
а зачем?
почему не на C#-пе?

bastii

А может еще у кого-нибудь есть эл. вариант
Addison-Wesley. Chris Sells. Windows Forms Programming in C#
Вроде тоже книжка хорошая.

serg-2000

димыч ты недоступен ни так ни по айпишнику.
а больше в сети твоей книжки нет.
а по подводу ошибок ничего подсказать не можешь?
заранее спасибо

serg-2000

заставил работать сей кусок следующим способом:
//Color newColor(255, 0, 0, 255);
Pen *pen = new Pen( Color::Red );
graphics->DrawLine(pen, 0, 0, 200, 100);
как ни удивительно работает, хотя очевидно что это только временно.
так как деструктор pen по неким магическим причинам не наличествует то delete pen не получается.
ну хоть как-то.

okunek

как это?
а че пишет, если delete pen вставить?

serg-2000

ну к этому относилась ошибка 2 из первого варианта кода.
а к delete pen отношение следующее:
error C3841: illegal delete expression: managed type 'System::Drawing::Pen' does not have a destructor defined
короче это все не менее удивительно чем то, что у колора нет конструктора ни с 4мя, ни с 3-мя аргументами (хотя я думаю не стоит говорить что они есть) а есть только конструктор копирования.

bleyman

error C3841: illegal delete expression: managed type 'System::Drawing::Pen' does not have a destructor defined
Блиа. Ты ёбу дался на managed C++ писать? Я ещё не встречал человека, который его понимает.
Данная конкретная ошыбка происходит из-за того, что Pen это манагед класс, и его автоматически сожрёт Сборщик Мусора. Поэтому деструктор у него снаружи недоступен. Вместо деструктора рекомендуется вызывать Dispose (чтобы он ресурсы освободил сразу же, а не когда до него сборщик мусора доползёт).
Пиши уже либо на шарпе, либо на обычных плюсах. Манагед С++ слишком мощный и непонятный для тебя.

bastii

Странно, что не доступен, а на др шары заходишь. Просто народ что-то скачивает. Проверь свои сетевые настройки. Книжку могу залить, хотя если поискать то, думаю, много у кого есть.
На С++ под дотНет я не писал. Для начала скажи на каком С++ пишешь. Просто в 2003 managed extentions c какими-то сранными ключевыми словами типа __gcnew и т.д. В 2005 сделали нормльный синтаксис, только там вроде ^ вместо * для ссылок на дотНет объекты. Короче я за совет Даркгрея писать на C#. Ну разве что ты фанат С++ных штучек Еще есть нативная либа GDI+, но не уверен, что стоит ее как-то с Винформами совмещать.

Dasar

Net - объекты нельзя через delete удалять - они сами удаляются

serg-2000

димыч не заходит никак. ну да ладно, я нашел твою вторую книжку, буду там смотреть если чего.
дело в том что я про шарп низнаю ровным счетом нихуя.
хотел обойтись. теперь вот буду разбираться. как я понял там разницы с с++ почти никакой и изучать толстенные книжки где все написано сначала меня вообще не прет.
кстати, а что в си-шарпе используется вместо указателей?

bastii

Только если много разных графических объектов в цикле приходится создавать, то лучше вызывать Dispose. А то они долго живут из-за ожидания файнализации, и что плохо, застревают в старших поколения GC.

Dasar

> кстати, а что в си-шарпе используется вместо указателей?
в C# - на уровне языка нет деления между указателями и не указателями.

otvertka07

указатели - зло, хотя в C++ мне очень нравился оператор -> (стрелочка) не знаю даже, почему, красиво выглядит

bastii

Согласен на стрелочки, только если можно как в Visual Assist - набираешь точку, а он на стрелочку заменяет

Irina22

а как без них?
если есть, скажем 3 класса
1) record - запись содержащая имя, телефон и т.д., а также указатели на 2 следующих, а также на сами деревья(SortbyName, SortbyPhone)
2) SortbyNameNode - элемент в дереве, отсортированном по имени
2) SortbyPhoneNode - тоже самое по телефону
если здесь можно без указателей, то я, пожалуй, переделаю прогу, которая почти готова

otvertka07

пиши на java или c#, там все то же самое прекрасно без указателей реализуется
в C++ нельзя, это язык стрелочек

bleyman

В шарпе нет указателей в том смысле, в котором они в С. Есть ссылки. При этом все сущности делятся на value types (enum, struct, int, float и т.д.) и reference types (всё остальное, то есть "обычные" классы). На валуе тайпы не бывает ссылок, на референс тайпы только ссылки и бывают. Ботай, короче, шарп. Он клиовый.

bastii

а unsafe?

Irina22

fj_ >В шарпе нет указателей в том смысле, в котором они в С. Есть ссылки.
fj_ >При этом все сущности делятся на value types (enum, struct, int, float и т.д.)
fj_ > и reference types (всё остальное, то есть "обычные" классы). На валуе тайпы
fj_ > не бывает ссылок, на референс тайпы только ссылки и бывают. Ботай, короче, шарп.
fj_ >Он клиовый.
спасибо, что знания освежил мои, оказалось, почти всё помню, хотя и давно это было и мало...
меня вот интересовало именно с++, потому что на нём сейчас пишу и под linux.

bleyman

Зачем ты это сказал? Думаешь, я не знаю про ансейф?

evgen5555

что у колора нет конструктора ни с 4мя, ни с 3-мя аргументами (хотя я думаю не стоит говорить что они есть)
Их как раз и нет.
Есть метод FromArgb.

bastii

to :
Ну тогда пиши на VC++ 2005, должно понравится.
to fj:
Да я не думаю, что ты про unsafe не знаешь. Просто я сам часто забываю, что такая фича существует. Так еще ни разу ей пользоваться и не приходилось.

serg-2000

кстати вопрос: C#
есть статик член parameters класса Interstate у него есть поле public const int BLA_BLA
при попытке обратиться Interstate.parameters.BLA_BLA пишет:
Static member 'NamesInterstate.ModelParameters.BLA_BLA' cannot be accessed with an instance reference; qualify it with a type name instead

Dasar

И что непонятно?
BLA_BLA - не является переменной объекта, соответственно для доступа к ней необходимо писать:
'NamesInterstate.ModelParameters.BLA_BLA'

serg-2000

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

serg-2000

а пока димыч не залил спрошу так:
как в с шарпе делать человеческую анимацию? в gui были битовые массивы, чем пользоваться втеперь чтобы все жутко не мерцало?

bastii

Можно где-нибудь в конструкторе формы сделать так:
 this.BackgroundImage = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); 
Потом включить двойное буфирезирование (свойство у формы без нее у меня почему-то форма сналача серый фон рисует, а потом поверх битмапку, в результате моргает.
Теперь можно рисовать сразу в эту битмапку и делать Invalidate области, которая изменилась, чтобы на форме перерисовалось.
Про то как лучше делать, если форма может размеры менять, я не знаю. Самому интнресно, может кто что предложит?

bleyman

Безморгательное рисование на винформах - это Высокое Искусство. Поэтому лучше всего его делать тупо и неинтересно - оверрайдить вндпроц и вешаться на старый добрый пейнт. Так ты получаешь 15 минут гемора и не очень хорошую расширяемость, зато гарантированно.
Иначе ты получаешь Бесценный Опыт за время от минуты до недели.

bleyman

А вообще где-то я этой цели вполне достиг. Всего лишь оверрайднув ОнПейнт. А что не так с ресайзом? Битмапка стретчится. Потом её можно пересоздать даже с новым размером.

bastii

лучше всего его делать тупо и неинтересно - оверрайдить вндпроц и вешаться на старый добрый пейнт.
И что дальше? Там по хорошему нужно изучить какие сообщения связаны с этим дело, в каком порядке они приходят окну и ее детям и т.д.
Про resize я имел в виду проблему, что нужно менять размер битмапы, а это должно жрать много ресурсов. Можно еще делать не одной битмапой, но это уже довольно сложно.
Кстати видел какие-то интересные ControlStyles, типа AllPaintingInWmPaint, OptimizedDoubleBuffer, UserPaint, только нужно разбираться как это может помочь. Хорошо, что хоть ResizeRedraw по умолчанию false.

bastii

В общем ждем Авалона, в вин апи с этим очень сложно бороться.

Dasar

Зачем Bitmap-ка?
Достаточно DoubleBuffer-а и UserPaint-а

bleyman

бррр. Повторюсь - зачем её ресайзить, если она эффективно стретчится?

serg-2000

большое спасибо димычу и фжэю за помощь!
возник очередной вопрос:
как узнать правильные относительные координаты мышки отн. формы (клиентской ее части).
есть абслютные. Form.Top LEft - координаты всей (и неклиентской части) (например заголовка окна и тд)
поле ClientRectangle вообще всекда Х и У держит нулями.

bastii

А что делает UserPaint?

Dasar

Отключает очистку background-а окна

bastii

Просто "стретчится" - не есть желаемый эффект. Потом DoubleBuffer уже в винформах реализован, хотя почему-то он не распространяется на child окна. Например, если будет стиль ResizeRedraw, то твоя отрисовка не будет будет моргать, но все child окна будут.Вопрос, как с этим бороться? Пока единственное что придумал, так это самому делать Invalidate на событие Resize, но исключать из облати инвалидации все прямоугольники, занимаемые child окнами. Хотя определнные нежелательные эффекты наблюдаются у границы с child окнами, эффект зависит от направления изменения размеров формы.
Еще не понятно пока, как бороться к морганием, когда используются контролы типа TabControl, который сам по себе моргает при изменении размеров. Причем у контролов SetStyle и DoubleBuffer, в отличии от формы, protected.

bastii

Странно, но похоже, что форма и так устанавливает UserPaint в true по умолчанию .

Dasar

> Причем у контролов SetStyle и DoubleBuffer, в отличии от формы, protected
Потому что эти контролы реализуются самим windows-ом - которому начхать на все эти DoubleBuffer и SetStyle

bleyman

Чо?

bastii

На сколько я понял, что double buffer работает в рамках одного WM_PAINT, а хотелось бы настоящего double buffering на уровне всего окна в плоть до отрисовки не клиентской области окна.

Dasar

Ты в курсе - что такое стандартные windows-контролы?
И чем они отличаются от нестандартных?

Dasar

> в плоть до отрисовки не клиентской области окна.
Неклиентская часть окна - даже в WinApi отдельно обрабатывается.
ps
В целом, можно сделать double buffering, основанный на NCPAINT-е

voronina

внимание вопрос - как теперь рисовать, что для этого надо сделать и ипользовать?
можно закинуть на формочку PictureBox. Рисовать на картинке bmp, когда придет время обновить этот picture box проверить, нужна ли перерисовка, и поменять data source на нашу картинку.

bastii

Кстати заметил, что с double buffering заметно быстрее перерисовка происходит. Рисовал порядка 200 окружностей на форме. Когда double buffer включен, форма мгновенно на изменение размера окна реагирует. А когда он выключен, так просто видно на глаз, как окружности в цикле рисуются, и наблюдаются заметные тормоза.
Не знаю, что может дать отдельно WM_NCPAINT. Сделать хотя бы процесс изменения размера окна нормально. Типа все окно в буфер, а только потом на экран. Но без нормальной инфраструктуры (которой в юзер32 нет аппарптной поддержки -- это просто нереально. Слышал, что изменение размера окна даже в последних версиях MacOS тормозит.
Похоже нужно забить. Возможно с Авалоном эту проблему получится решить.

serg-2000

димыч!
дабл буфферинг включил (из мсдна выдрал)
затем как ты сказал
this.BackgroundImage = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
потом когда надо создаю контекст и рисую в этот битмап,
потом чтобы отрисовать это методом проб и ошибок накропал это:
graphics = this.CreateGraphics;
PaintEventArgs e = new PaintEventArgs(graphics, this.ClientRectangle);
this.InvokePaintBackground(this, e);

graphics.Dispose;
я правильно реализую?

serg-2000

кстати:
как получить доступ к цвету формы (типа цвет Control) - чтобы заливать форму при рисовании а то она прозрачная отрисовывается вначале?
ответте пожалуйста на мой вопрос с мышкой!

bastii

А где ты берешь коорд мыши не относительно клиентской области формы, все мышиные события возвращают в относительных координатах. В любом случае у формы есть метод PointToClient.

bastii

потом чтобы отрисовать это методом проб и ошибок накропал это:
graphics = this.CreateGraphics;
PaintEventArgs e = new PaintEventArgs(graphics, this.ClientRectangle);
this.InvokePaintBackground(this, e);
graphics.Dispose;
я правильно реализую?
Проще у формы Invalidate вызвать.

bastii

как получить доступ к цвету формы (типа цвет Control) - чтобы заливать форму при рисовании а то она прозрачная отрисовывается вначале?
не совсем понял, но есть SystemColors, там можно взять SystemColors.Control

serg-2000

Проще у формы Invalidate вызвать.
поэтму и спрашиваю. я попробовал - по неизвестным мне причинам программа просела в полный даун.
область в кот. анимация отрисовалась и не перерисовывается и даже (!) не отрисовываются кнопки хотя работают. короче полный атас.
не знаю по каким причинам но тот что я написал до этого получившись абсолютно случайно работает.
насчет мышки - я овверрайдел ОнКлин а туда не передается никакой информации о положении (это я в мсдне вычитал, но не прочитал что в след. предложении советую оверрайдить онМаусДаун. сделал - все ок. спасибо)
позицию брал из Control.MousePosition

bastii

Это странно, что из-за Invalidate гуи повисает, я думал, что он вообще ничего не сендает (для этого есть UpdateWindow).
Ты под какую VS пишешь? И может тогда запости код для формы.
Оставить комментарий
Имя или ник:
Комментарий: