tag:blogger.com,1999:blog-82751044423985991212024-03-05T04:02:49.072-06:00Timothy's ThoughtsTimothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.comBlogger1284125tag:blogger.com,1999:blog-8275104442398599121.post-88841686450655561722024-01-08T06:39:00.000-06:002024-01-08T06:39:01.516-06:00Why Did You Believe and Others Did Not?In an encounter with some Calvinists, one of them kept asking (more like demanding) why did you believe but others didn’t? Being that they are Calvinists, what they want to say is that the reason one person believes and others don’t is because we’re just following our nature. They want to say that God gave some people a nature to believe and others a nature to reject him. They like asking that question because it gives them a nice simple answer, while those of us who believe that the nature God gave us is to have the freedom to make choices have a hard time answering it. I can point to plenty of things that led up to me accepting Christ, but I can no more say why I made that choice than I can say why I sometimes choose vanilla ice cream and sometimes chocolate ice cream. So, I told the person that I could no more answer that than they could answer why God chose them.
Interestingly, the person responded by saying, “I know why God chose me,” and then he quoted, Ephesians 1:5, “Having predestinated us unto the adoption of children by Jesus Christ to himself, according to the good pleasure of his will.” This is interesting, because, though I have problems with the way they are using this verse, the fact that they did use this verse in this way gives me a way to answer their question. Obviously, if God choosing us by “his good pleasure” is a sufficient answer for why God exercised his freewill in the way they believe he did, then for me to say that “it was my personal preference” is a sufficient answer for me to explain why I made the decision that I did through my freewill.
As you might expect, the Calvinist wasn’t satisfied with my answer. The problem that Calvinists have is that they presuppose determinism. They don’t really want an answer to “Why did you believe but others didn’t?” They want an answer to “What is the deterministic reason that you believed but others didn’t?” Of course, that is just question begging. If God has freewill and God has the power to make creatures that have freewill, then we can’t just assume that our every action is predetermined.
To make it worse, Calvinists borrow from the concept of freewill to keep their doctrine from making God the author of sin. They will say that we’re just following the sin nature that God made us with, but God isn’t the cause of our sin. If you mention that their doctrine makes God the author of sin, they squirm like worms when you remove the rock they are hiding under. They never provide a good explanation for it, rather they say things like, “You don’t understand Calvinism” or “You can’t understand things that are spiritually discerned, because you are carnal.” When the simple fact is that their doctrine is just wrong.
Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-34591496540156231332023-09-25T10:42:00.003-05:002023-09-25T10:42:47.561-05:00I Would Dump ProPresenter If I CouldIt's no secret that I have been vocal about issues with ProPresenter 7. We have frequently had issues in which ProPresenter would crash at inopertune times. Up until this time, my hope was that by being the sqeaky wheel they would fix the problems that I have been seeing. Instead of doing that, this weekend, RenewedVision chose to block my access to a forum that they moderate on Facebook and also their own Facebook page. The only post that I know they took issue with was "Is anyone else seeing multiple crashes that aren't reported by the crash reporting system." Aside from that, I made some comments concerning problems with their software development process. My initial assumption was that someone unassociated with Renewed Vision was resposible for blocking me, or perhaps, one employee who hadn't been trained properly. But after contacting them directly, it was revealed to me that it was, in fact, a RenewedVision employee who chose to block me and that it was a decision made by multiple employees. This is quite disturbing to me. I would not expect such unprofessional behavior coming from a significant software development company. Blocking customers because they ask a question that you don't want answered or because they see problems with your software development process is extremely unprofessional.
So far, they haven't blocked me from submitting trouble tickets, but I'm now concerned that they might be picking and choosing which bugs they fixed based on whether they like you or not. I have since discovered a way to get rid of the crash that I was seeing. I deleted the Timers configuration file and then went and recreated the timers, one-by-one. It appears that the Timer's file was corrupted when either the installer or the startup code ran. But I didn't get there by RenewedVision providing me with a solution; I got there by asking that same question that RenewedVision took issue with on another forum and the resulting answers resulted in me finding an answer to the problem.
I'm so tired of messing with these guys. If not for the fact that I don't believe there is other software out there that does what their software does, I would be trying to get rid of ProPresenter. In the past, I have encouraged people to try ProPresenter, but I don't know that I can encourage people to try ProPresenter when I have serious concerns about the professionalism of the company that develops it.Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-89085628615780052912020-03-19T07:29:00.000-05:002020-03-19T07:29:51.956-05:00Understanding God in Times of Suffering and Uncertainty<span class="drop-caps">H</span>ow do we pray during something like this? In the news we hear about this crazy bug that is going around. We know it is causing suffering and with so much news about it it almost feels like it is hanging in the mist around us, even though the numbers indicate that’s not the case. Even if we don’t catch the bug, we’ve been affected. Some are off of work. Others wish they were off work because they worry every time they hear a co-worker cough. Normal is disrupted. How do we pray in times like this.<br />
<br />
My thoughts turn to Romans 8. Paul was discussing some things here that often get overlooked because of some controversial doctrinal issues that laid on this passage, but it’s worth our time to focus on what he was saying and not just the doctrinal implications of the example he gave. In Romans 8:16-18 he states, “The Spirit itself beareth witness with our spirit, that we are the children of God: and if children, then heirs; heirs of God, and joint-heirs with Christ; if so be that we suffer with him, that we may be also glorified together. For I reckon that the sufferings of this present time are not worthy to be compared with the glory which shall be revealed in us.” Paul was dealing with a different type of suffering, but he saw the suffering that he was going through as evidence of his future glorification.<br />
<br />
It is within Paul’s discussion of suffering that he says, “Likewise the Spirit also helpeth our infirmities: for we know not what we should pray for as we ought: but the Spirit itself maketh intercession for us with groanings which cannot be uttered. And he that searcheth the hearts knoweth what is the mind of the Spirit, because he maketh intercession for the saints according to the will of God.” (Romans 8:26-27)<br />
<br />
This is a difficult thing. We don’t like going through suffering. We don’t like seeing other people suffering. But that suffering may result in something far greater that we can’t see, yet. It’s hard for us to pray for things we can’t see, but the Spirit intercedes for us. That’s not to say that he is asking that we be protected from suffering. Whatever the Spirit asks for will be given, but that may still cause us to suffer. That’s very difficult.<br />
<br />
But notice what the next verse says, “And we know that all things work together for good to them that love God, to them who are the called according to his purpose.” (Romans 8:28) We like to quote this and think about all the blessings that are going to come our way, but he just been talking about suffering. What are those “all things”? Suffering. Maybe some other things too, but definitely suffering.<br />
<br />
There’s something that I really like about this verse. He doesn’t just say, “all things work together for good” as if he is giving his readers knew information. Instead, he begins with “and we know.” For a long time I looked at that and questioned, “how do we know that?” Paul says we know it (or at least he and his original readers knew it). Am I supposed to look at my own life and somehow it seem obvious? No, I don’t think so. This passage wouldn’t be needed if we could get there by self-reflection.<br />
<br />
Recently, I’ve become convinced that the controversial verses (Romans 8:29-30) are there to provide evidence for his claim that we know these things. “For whom…” it begins. That “For” is pointing back at the verse saying, “we know.” So, he’s about to tell us why we know it. “For whom he did foreknow, he also did predestinate to be conformed to the image of his Son, that he might be the firstborn among many brethren. Moreover whom he did predestinate, them he also called: and whom he called, them he also justified: and whom he justified, them he also glorified.”<br />
<br />
One way that people read this passage is to say that those he foreknew are all of us who will be saved. Since that would include us today, they explain the tense of the passage by saying that this means it was started in the past but is an ongoing thing, so even though we haven’t been glorified yet, it is just saying it has started and it is certain. My objection to that view is that it takes something that isn’t obvious (verse 28) and gives evidence for it with something that is even less obvious. Paul was too well educated to make that kind of mistake in his writing.<br />
<br />
There is another way to look at this passage. What if “foreknow” actually means, “people known in the past?” What if it means people who came before Paul, but not Paul himself? Do we know of people that God knew before Paul, that he predestinated to be conformed to the image of his Son, that he called, that he justified, and that he glorified? What about Moses and Elijah? When they appeared on the mount of transfiguration, Peter wanted to build tabernacles for them. Elijah was taken up into heaven at the end of his ministry. He is an obvious example of a saint of old who was treated as if his sins were forgiven prior to the sacrifice that Jesus offered on the cross, a person called by God, and a person who was glorified. How do we know that Romans 8:28 is true? Because it was true for people like Elijah and other examples we have in the scriptures. <br />
<br />
We have evidence that God works all things for good. Even the suffering that we face will be turned to good. And I think we can already see hints of that happening with our current situation. We don’t want to pray for suffering, even though it may lead to better things. We may even question why God would allow suffering. We might even be tempted to say that God could have prevented it and should have prevented it but didn’t. It’s true that God could have prevented it, but before we start telling God what he should do, we should look at the examples we have in the Bible of how he used suffering to accomplish better things. We don’t know what the end result of this suffering will be, but we can have faith in God and his ability to turn it into something good.<br />
Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com1tag:blogger.com,1999:blog-8275104442398599121.post-53898120703453088502020-03-18T12:19:00.000-05:002020-03-18T12:19:43.000-05:00Using Video Conferencing for Church Work During Troubled Times<span class="drop-caps">W</span>ith the efforts to slow the spread of the virus, most churches are running up against meeting size limitations and ours is no exception. But we can’t just drop everything and wait for this thing to blow over. The work of the church must continue. One way of doing that is by holding staff, team, committee, etc. meetings online, rather than in person. Having recently conducted a committee meeting like that, I thought it might be beneficial to someone if I were to document what I did and why. Please, do not take this to be an expert opinion on how these things should be done. I went into this looking for a low cost solution that I could set up quickly. I did not evaluate all of the options and there may be a better solution out there.<br />
<h2>Tool Selection</h2>Going into this, my first thought was, “How can I do this with Skype?” We’ve been using Skype for Business at work for a long time, so I knew that was one possibility and it is one that would do what I needed it to do. Skype has better name recognition, but in the end, I chose to use Microsoft Teams (free). Microsoft owns both, but Teams it seems like they are trying to transition business type meetings from Skype to Teams. I chose to go with Teams, partly because I wanted to try it out and partly because there is a free version that has a lot of the functionality that you pay for when using Skype for Business. There are other tools out there that I’ve seen people use, such as Go To Meeting and Zoom. I don’t know how those compare, but the free version of Microsoft Teams will allow up to 300 users (as opposed to 50 users on Skype). Though I don’t anticipate us doing this, 300 users would be more than enough to have all of the people who attend our services in the user list. <br />
<h2>Setup</h2>The starting point is <href="https://teams.microsoft.com">https://teams.microsoft.com</href>. Microsoft will ask for your Microsoft user id and password. I pretty much just clicked through stuff until I figured out what seemed to work. I created a Team for the committee that I wanted to meet with and added them one by one. Since the free version of the tool doesn’t allow for scheduled meetings, I sent out an e-mail saying what they would need to do to join the meeting when it was time to meet, though it turns out that once a meeting is started I had some capability to add them to the meeting and to send a link they could use to join the meeting. If we were going to do this a lot, I would think that being able to schedule a meeting would be worth paying the fee, but we did alright with just the free version.<br />
<br />
In the meeting room, we had three people, so I set up a video camera connected to a laptop via a video capture device. The others were connected via their phones or laptops. Some had their cameras turned on and some did not. I was able to join the meeting via my laptop and my phone at the same time. That allowed me to see what other people were seeing. One issue I didn’t figure out was that the video was reversed. This wasn’t a big deal because I wasn’t trying to show people anything through the video, but it was odd.<br />
<h2>The Meeting</h2>Most of what we did was discuss some documents that I made available by sharing a screen. If you have multiple screens, you can choose which screen you share, or you can share a particular application. Because people were viewing it through their phones, it was difficult for them to read. If everyone had been using desktops, laptops, or tablets, it probably would’ve been better. We did run into some issues with echoes and noise, but that seems to be the nature of the beast. Sometimes the sound would drop out while people were talking, making it hard to understand.<br />
<br />
Our biggest problem wasn’t technology but lack of feedback. In a normal committee meeting, when reviewing a document, silence means people have nothing to say that they are intently looking a that document, trying to figure something out. Body language tells you which is which. On a video conference, it is much harder to pick up on those cues, even if you can see people’s faces, making it much harder to know when it is safe to move on. Move too slow and it takes forever. Move to fast and you end up with just one person talking and the others get overlooked.<br />
<br />
I don’t want to say that these tools aren’t really designed for deliberative bodies because I would imagine that if the rule that Robert’s Rules of Order puts in place for meetings of more than 12 people then some of the issues would be resolved, since each person would have to be acknowledged by the chair prior to speaking. There would just need to be a way for them to inform the chair that they wished to speak. And a classroom setting sort of follows those same rules. It’s the small committee that has more of an issue because people tend to just speak and usually that is the best way to handle them. But the lag from when someone speaks and when their voice is heard online causes people to talk over other people.<br />
<h2>Opportunities for These Tools</h2>Committee meetings seem to be the closest things that churches have to the target group for a tool like Microsoft Teams, even though it isn’t ideal. I’m of the opinion that churches should make use of that. Given that a lot of other stuff has been canceled, this may be a good time for these committees to get more stuff done that scheduling conflicts may have hindered in the past. I’m very much of the opinion that it is in working groups that true church fellowship is developed.<br />
<br />
Small groups and Sunday school classes are another place where these types of tools may be ideal. We might not have considered doing something like this when we weren’t required to limit gathering sizes, but now is a good time to try things that wouldn’t normally work.<br />
Though probably better for normal Skype or Facetime than for a tool like Teams, video conferencing may be a good way to communicate with “shut-ins”. In fact, we’re kind of in a situation where we’re all supposed to be acting like shut-ins. There’s only so much Netflix you can watch before you get bored. Imagine it that were your life all the time.<br />
<br />
For a church service, you probably want to stick with normal livestreaming. It would be great if we could all hear each other singing and worshiping together, but the lag would make that difficult. But want a church might do is have the pastor, the music director, and maybe a few others be on a meeting together and then livestream that meeting. They might each be in their own homes, but the music director might begin the service, someone else might have announcements (what’s church without announcements), the pastor would preach a sermon. And everyone else would participate from home without the disruption that random open mics would cause.<br />
<br />
What about outreach? Well, there’s no reason you can’t lead a person to the Lord over a video conference. The big question is whether there is something we can do to get them on that video conference in the first place. As with all things related to outreach, that may require some creativity. Maybe we invite them to participate in a discussion of some kind. Maybe its something else. But yes, I think it is something that might work.<br />
Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-12022661843737399362020-03-13T09:15:00.000-05:002020-03-13T09:15:23.239-05:00Psalm 91 and Coronavirus<span class="drop-caps">A</span>mid the talk of coronavirus, I’ve seen plenty of posts about Psalm 91. Many focus on verse 10, “There shall no evil befall thee, neither shall any plague come nigh thy dwelling.” One preacher declared that if people would claim this promise that the virus would stay away. It bothers me when I hear people make claims like this because simple observation tells us that Christians are not immune from viruses, or cancer, or automobile accidents, or anything else. How are we to explain this? Is it a lack of faith? Is God a liar? Does this passage even mean what people think it does?<br />
<br />
Psalm 91 is a reassuring passage to read because it mentions many protections that only God can provide in a way that says it will be done. But does it really say that we can go to the Lord and say, “You promised that I wouldn’t get sick?” It’s interesting to note that Satan used this same passage when he tempted Jesus to throw himself down from the temple, but equated this with “tempt[ing] the Lord thy God.” If Jesus wouldn’t use the passage in this way, should we?<br />
One of the questions we should answer is who this passage is written to and about. Our tendency is to look at any of the Psalms and make it about us. Verse 1 says, “He that dwelleth in the secret place of the Most High shall abide under the shadow of the Almighty.” We want to interpret this as “If I dwell in the secret place of the Most High then I will abide under the shadow of the Almighty.” Then we try to figure out what the “secret place” is and start making up things. We might say that those who are a Christian dwell in the secret place. But then we think that maybe it is really only those Christians who have a very close relationship with the Lord. This gives us an out if we or some other Christian gets sick because we can always say that our relationship with the Lord isn’t as good as it should be. But this is not how we should interpret scripture.<br />
<br />
It’s interesting that the writer of this Psalm refers to the Lord as his refuge and fortress, but he seems to be talking to someone who has “made…the Most High, [his] habitation.” It brings to mind a walled city, which would be a “refuge and fortress” for the people who lived outside the city, but would be a dwelling place for people who had homes in the city.<br />
Some people think that Psalm 91 is a psalm of Moses and suggest that the “secret place” might refer to Moses meeting with God in the cloud on the mountain. But other people think this is a psalm of David, which might call that interpretation into question. Psalm 18:11 says that the Lord “made darkness his secret place,” and has references to a severe storm. Psalm 27 speaks of the secret places of the Lord’s tabernacle and of dwelling in the house of the Lord. Psalm 81 refers to “the secret place of thunder.”<br />
<br />
Here’s a possibility that seems to fit the context and what we know: maybe dwelling in the secret place isn’t continual, but is a place that we go for refuge in times of trouble. But it’s not up to us to choose whether we are in the secret place or not. When the Lord “covers thee with His feathers,” that is when you are in the secret place. We can run to him for help and request that he cover us to protect us, but just as Jesus would not throw himself from the temple to test this, we should not put ourselves in harm’s way just to try it out. And we should not assume that this protection will give us long life on Earth. It may be that the Lord will protect us by taking us to be with him in heaven. And as it relates to the coronavirus, yes, we can seek the Lord’s protection, but it could be that he protects some of us by allowing us to contract the virus. It may be uncomfortable for a time, but we may come out with immunity to that virus on the other side. And if it kills us and we are in Jesus Christ, we will enter into a life that is better than what we know now. <br />
Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-81183013920940511082020-02-14T16:08:00.001-06:002020-02-14T16:08:42.946-06:00God's Valentine<span class="drop-caps">V</span>alentine’s Day is that special day when those of us who are single feel miserable because we are alone while those who are not single are all mad at their significant other for not being romantic enough. At this point in my life, I’ve spent a significant amount of time considering the question of why I’m not married. And I’ve had plenty of people give me their own thoughts on the subject. I used to have people tell me that “God has someone for you.” I believed them. And I heard of people who spoke of what they believed was God putting them together with their perfect match. While it made for a great story, I couldn’t reconcile the logic of it. For one thing, there were far too many divorces. If God were picking and choosing the people to place together in marriage then why would there be divorce? Either there were people who married when they should have waited for the right person to come along, or they were rejecting the one God had chosen. The second might have been true, but they were getting remarried. God hates divorce. Though it’s not the unforgiveable sin, I couldn’t get my head around how God could say he hated divorce and then use that as the means by which to bring the right two people together. And if he didn’t want to split people up then that might mean that the woman God intended for me married the wrong person. <br />
Granted, it’s exactly my kind of response. If someone were to ask me, “Why aren’t you married?” I could see myself saying, “The woman God had for me married someone else.” While it would get plenty of strange looks, that is consistent with what many people believe about marriage. There is, however, another way to understand marriage that doesn’t run into the same logical problems. What if—as a general rule—God doesn’t pick who or if we will marry. That’s not to say that he never does, nor that he won’t give us advice on the subject, but what if that is something he leaves up to us and if we choose to marry a terrible person and we’re miserable, well, that’s on us. That gets us away from thinking that God caused us to marry the wrong person. That gets us away from thinking that maybe we should consider marrying someone who isn’t right because God hasn’t seen fit to bless us with the right person. It gets us away from thinking that two people who are married maybe aren’t right for each other. <br />
Some may object that if God leaves the choice up to us then he doesn’t have foreknowledge of who we will marry. This objection is a logical fallacy. Knowledge of an event doesn’t equal causation. We might have knowledge, for example, that a train is traveling from Fort Worth to Dallas. We might even be able to describe each bend it will make along the way. We might even be able to say when it will travel through each railroad crossing, but we didn’t cause any of it. Given that God’s knowledge far exceeds our own, there is no reason for us to think that he must control every detail of future events in order to know what those events are.<br />
Another objection that people might have is that it makes it seem like God doesn’t care who you marry. I don’t think anything could be farther from the truth, but what it might be is that there is a certain type of person that he would want you to marry. Instead of thinking there is one person that would give you the best possible marriage if you were to marry them (but they might mess that up by marrying the wrong person), think about it in terms that God is going to bless or curse certain aspects of your marriage and if you marry the type of person that God would have you marry and live according to how he would have you live that you are putting your marriage in a position to blessed. But if you choose to marry a prostitute, you’re putting yourself in a position to live out the life of Hosea. You aren’t going to miss out on the best marriage because “the one for you” chose to marry someone else and you aren’t necessarily going to have the best possible marriage because you asked God to lead you to the person you should marry.<br />
What does this mean for Valentine’s Day? For one thing, if you are married, you have a responsibility to nurture the relationship you are in because it’s not going to last just because God picked the right person for you. You picked ‘em. As for those of us who are sitting at home and once again bemoaning the fact that we have no one who is expecting us to buy them roses, chocolate, and white teddy bears made in China, we have no reason to question God on the subject. He gave us the ability to go out in search of such a person, and he might have given us sense enough to make good choices, so that we got here, not because God likes us less than he does other people, but because we are better off than if we made bad choices. Or maybe we’re in this situation because we made bad choices. Either way, if you are sitting around asking why God hasn’t given you the Valentine that you wanted this year, you should find a better use of your time.<br />
<br />
<br />
Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com1tag:blogger.com,1999:blog-8275104442398599121.post-35583411349164547822019-12-03T14:39:00.000-06:002019-12-03T14:41:16.956-06:00Reasons for Old Earth/Young Earth<span class="drop-caps">W</span>hat are the arguments for saying that the Earth is old and what are the arguments that the Earth is young? Below is a list of some that I have heard on both sides. I doubt that anyone will read this and go away having changed their mind on the position they hold. I do, however, think that if someone wishes to argue their position they will need to address the reasons that are given on the other side.<br />
<br />
<table><tr><th>Reasons for Young Earth</th><th>Reasons for Old Earth</th></tr>
<tr><td>The Bible says creation took six days.</td><td>The word used for "day" could be translated as "period."</td></tr>
<tr><td>The Bible says that Adam was "in the beginning."</td><td>The word "day" is used multiple ways in Genesis 1.</td></tr>
<tr><td>The great flood would have removed evidence of anything prior to it.</td><td>Hebrews 3 implies that we are still in the seventh "day."</td></tr>
<tr><td>The geniologies have enough people to cover about 6,000 years.</td><td>Genesis 1:12 declares that "the Earth brought forth," implying that it took some time for the plants to grow.</td></tr>
<tr><td>Young Earth best accounts for a world in which no death occurred.</td><td>Adam was allowed to name the animals before Eve was formed. It likely would have taken more than one day name the animals.</td></tr>
<tr><td>The existence of fossils is evidence that the layers of rock were formed much more quickly (such as by a global flood) than would be implied by rock layers forming over millions of years.</td><td>The amount of time required for light to travel from the stars to us is more than 6000 years./td></tr><br />
<br />
<tr><td>Radiometric data cannot be shown to prove millions of years.</td><td>The Bible doesn't say that the animals didn't die, or anything, other than those who had access to the Tree of Life.</td></tr><br />
<br />
<tr><td></td><td>The Bible doesn't make a direct statement about the age of the Universe or of the Earth.</td></tr><br />
<br />
</table>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-9779338135151570842019-09-09T10:38:00.001-05:002019-09-09T10:38:56.611-05:00The Ticking Clock<span class="drop-caps">I</span> remember thinking when I was a kid that stories were just a segment of the characters lives. You could think of an author picking a beginning point of the story at some key event, finding a good end point, and just giving the details of what happened in between. But as I began to write my own stories, I discovered that this isn’t the case at all. It may be true of the beginning and ending, but it’s that middle stuff that gets you. When outlining a story, there are some key things that have to occur at various places in a book. The setup for the story always occurs at the beginning, even if you have to rip it out of the middle of the sequential order or even after the end of the story. The reader has to understand what is going on and why it is important. Then the characters have to be seen doing their thing. This is where the reader really starts to enjoy living in this world we’ve created, but it only goes on for about the second quarter of the book. Then it all falls apart. The world that the reader has been enjoying is in danger. And then we tell how the threat was dealt with, for good or for ill. These may not occur sequentially along a timeline, but we must put them in this order in the story.<br />
<br />
But you know all of that. What I’ve noticed recently is that there are some things that really are in sequential order. I tend to think of these things as the tick of a clock. Suppose our story begins with a massive explosion on Monday. As the story unfolds, the characters are going to move into the activities of Tuesday. These are different activities than would be in the story if the explosion occurred on Friday and they moved into the activities of Saturday. There are also activities that occur every day, like getting out of bed, or making coffee in the morning, or fixing lunch. We don’t think about these activities much because they usually aren’t key to the story, but we hang our story off of them as we move along. Let me see if I can explain this.<br />
<br />
Suppose we had the exciting explosion to pull the reader into our story, but now the outline calls for setup. We want to establish that the protagonist is impacted by this explosion in some way. It happened on Monday, let’s say in the afternoon. What’s on his schedule on Monday afternoon? He’s driving home from work. Traffic is a mess because people are looking at the fire. Maybe he receives a phone call telling him that he needs to return to work because of this. The story progresses, but his normal activities are a constant. These ticks of the clock are those things he would’ve been doing if not for the event he is impacted by. In the story, we are establishing that he is an investigator who looks into explosions like this, but the clock is ticking forward, and he would normally be in bed. Because of the explosion he isn’t in bed, but he is tired after having had a long day already. The clock ticks forward to Tuesday morning. We’re still doing setup and we want to establish that he is a single father. We don’t have him cancel a trip to an amusement park for the kids, instead we look at the clock and have him trying to find someone to take his kids to school.<br />
<br />
What I find interesting about these ticks of the clock is that they flow naturally into the story. It’s almost like we don’t have to make them up because they are just part of who the character is. On the one hand we’re looking at our outline and making up stuff that fits the outline, but on the other we are just watching the clock and writing down what is occurring at each tick. It’s that blend of the two that makes the story. <br />
Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-9721539251990271822019-07-25T12:30:00.000-05:002019-07-25T12:30:08.503-05:00Engaging the Lost<span class="drop-caps">A</span>fter watching several videos from the One for Israel Ministry (<a href="https://www.blogger.com/www.oneforisrael.org">www.oneforisrael.org</a>) I began to notice a trend. Many of these Jews who have come to accept Jesus as their messiah declare that they were surprised to learn that Jesus was a Jew. Some chose not to read the New Testament because the rabbis told them not to and they assumed that the New Testament was instructions to Christians to persecute Jews. “Jesus is not for us” is a common theme that these people were taught. So when they began to learn about Jesus being a Jew, and reading the New Testament that is written by Jews and about the Jewish scriptures they were shocked.<br />
<br />
I don’t know many Jews, but I encounter plenty of gentiles who speak of God in ways that are inconsistent with who I know God to be. They speak of God as being an evil being and I question how anyone could read the Bible and come to that conclusion. But that’s just it. They haven’t read the Bible. They don’t know my Jesus. These people aren’t rejecting Jesus based on what they know about him but out of their ignorance. They speak as if they know. They speak as if they have read the scriptures. They may even quote from the scriptures, but they haven’t read to understand.<br />
<br />
Just as Jews need to be shown passages like Isaiah 53 to help them see that Jesus is the prophesied Messiah, those who hate God need to be shown the scriptures in such a way that they can see that God isn’t what they think he is. We should not assume that just because they say they have read the Bible or that just because they reference scripture that they know what Christianity is about.<br />
<br />
I think it is important for us to engage people on social media in such a way as to oppose the sin of the world. The more controversial the more important it is that we engage in these conversations because this is our opportunity to engage the lost. But it must not stop there. It isn’t enough to state that abortion is wrong, the divorce is wrong, that homosexuality is wrong, that the sins of the world are wrong. Doing that will make people angry enough to argue with us, but if we don’t turn the conversation to teaching God’s word then it is of no value. If we do use these conversations to teach God’s word then it can be of great value. These people may never read the Bible except for what we spoon feed them in these conversations. I don’t expect that I will ever win someone to Christ during one of these arguments, but it may convince someone to go read for themselves. If we can do that then they may be persuaded.Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-74920618131804961512019-05-21T20:29:00.001-05:002019-05-21T20:29:40.988-05:00A 3D Python Maze for Art of Illusion<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik-QMN5PNLRpmIO-87FtFSKyjxqzwa2EMcnwyvo7UxhCS5ox4m6jGkFOfQBtL0EJgiQSHnVtGpli9uhegFmUQZZX5MEjhqsEcYgfAU8pZlWr1WDg3gpszPmSsHo4AUwVx9jedhMKWjfQ/s1600/BigMaze.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="960" data-original-width="1280" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik-QMN5PNLRpmIO-87FtFSKyjxqzwa2EMcnwyvo7UxhCS5ox4m6jGkFOfQBtL0EJgiQSHnVtGpli9uhegFmUQZZX5MEjhqsEcYgfAU8pZlWr1WDg3gpszPmSsHo4AUwVx9jedhMKWjfQ/s400/BigMaze.png" width="400" /></a></div>
<span class="drop-caps">I</span>'ve always had a fascination with mazes. While messing with the Python plugin for Art of Illusion I decided to write a maze generator in Python. The image to the right is a rendering of the maze that is produced by that code. I did it as a Scripted Object, which was probably not the best idea since it recalculates the maze whenever something changes, but my excuse is that I was testing out some things related to Python scripted objects in Art of Illusion.<br />
<br />
I'm including the code below, but with the caveat that it has a defect at one of the boundaries that I haven't figured out yet. It doesn't remove a wall for one or two of the cells. Aside from that, it will produce a good 3D maze.<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">import random</span><br />
<span style="font-family: "Courier New", Courier, monospace;">mazeWidth = 25<br />mazeLength = 25<br />wallLength = 1.2<br />wallHeight = 2.25<br />wallThickness = 0.05</span><br />
<span style="font-family: "Courier New", Courier, monospace;">WALL_UP = 0<br />WALL_DOWN = 1<br />WALL_FIXED = 2</span><br />
<span style="font-family: "Courier New", Courier, monospace;">class cell():<br /> X = 0<br /> Y = 0<br /> N = WALL_UP<br /> S = WALL_UP<br /> E = WALL_UP<br /> W = WALL_UP<br /> visited = False<br /> <br />def createmaze(width, length):<br /> m = []<br /> for l in range(length):<br /> row = []<br /> for w in range(width):<br /> _cell = cell()<br /> _cell.X = w<br /> _cell.Y = l<br /> row.append(_cell)<br /> m.append(row)<br /> <br /> for l in range(length):<br /> m[l][0].N = WALL_FIXED<br /> m[l][width-1].S = WALL_FIXED<br /> <br /> for w in range(width):<br /> m[0][w].W = WALL_FIXED<br /> m[length-1][w].E = WALL_FIXED<br /> <br /> return m<br /> <br />def createWall(length, height, thickness):<br /> wall = Cube(thickness, length, height)<br /> return ObjectInfo(wall, CoordinateSystem(), "")<br /> <br />def drawMaze():<br /> for i in range(mazeLength):<br /> for j in range(mazeWidth): <br /> if maze[i][j].W != WALL_DOWN:<br /> obj = createWall(wallLength, wallHeight, wallThickness)<br /> if not obj is None:<br /> obj.getCoords().setOrientation(90.0, 0.0, 0.0)<br /> obj.getCoords().setOrigin(Vec3(j*wallLength-(wallLength*0.5)-(mazeWidth*wallLength/2), wallHeight/2, i*wallLength-(mazeLength*wallLength/2)))<br /> self.addObject(obj)<br /> <br /> if maze[i][j].N != WALL_DOWN:<br /> obj = createWall(wallLength, wallHeight, wallThickness)<br /> if not obj is None:<br /> obj.getCoords().setOrientation(90.0, 90.0, 0.0)<br /> obj.getCoords().setOrigin(Vec3(j*wallLength-(mazeWidth*wallLength/2), wallHeight/2, i*wallLength-(wallLength*0.5)-(mazeLength*wallLength/2)))<br /> self.addObject(obj)<br /> <br /> for i in range(mazeLength):<br /> obj = createWall(wallLength, wallHeight, wallThickness)<br /> if not obj is None:<br /> obj.getCoords().setOrientation(90.0, 0.0, 0.0)<br /> obj.getCoords().setOrigin(Vec3(mazeWidth*wallLength-(wallLength*0.5)-(mazeWidth*wallLength/2), wallHeight/2, i*wallLength-(mazeLength*wallLength/2)))<br /> self.addObject(obj)<br /> <br /> for j in range(mazeWidth):<br /> obj = createWall(wallLength, wallHeight, wallThickness)<br /> if not obj is None:<br /> obj.getCoords().setOrientation(90.0, 90.0, 0.0)<br /> obj.getCoords().setOrigin(Vec3(j*wallLength-(mazeWidth*wallLength/2), wallHeight/2, mazeLength*wallLength-(wallLength*0.5)-(mazeLength*wallLength/2)))<br /> self.addObject(obj)<br /> <br />def chooseUnvisited():<br /> neighbors = []<br /> if (current.N == WALL_UP) and (current.Y-1 >=0) and (not maze[current.Y-1][current.X].visited):<br /> neighbors.append(maze[current.Y-1][current.X])<br /> if (current.S == WALL_UP) and (current.Y+1 < mazeLength) and (not maze[current.Y+1][current.X].visited):<br /> neighbors.append(maze[current.Y+1][current.X])<br /> if (current.W == WALL_UP) and (current.X-1 >=0) and (not maze[current.Y][current.X-1].visited):<br /> neighbors.append(maze[current.Y][current.X-1])<br /> if (current.E == WALL_UP) and (current.X+1 < mazeWidth) and (not maze[current.Y][current.X+1].visited):<br /> neighbors.append(maze[current.Y][current.X+1])<br /> <br /> if len(neighbors) > 0:<br /> return random.choice(neighbors)<br /> else:<br /> return current<br /> <br />def removeWall(cur, nxt):<br /> print("Cur "+str(cur.X)+" "+str(cur.Y))<br /> print("Nxt "+str(nxt.X)+" "+str(nxt.Y))<br /> if nxt != cur:<br /> if cur.Y < nxt.Y and cur.S != WALL_FIXED:<br /> print("removeWall 1")<br /> maze[cur.Y][cur.X].S = WALL_DOWN<br /> maze[nxt.Y][nxt.X].N = WALL_DOWN<br /> elif cur.Y > nxt.Y and cur.N != WALL_FIXED:<br /> print("removeWall 2")<br /> maze[cur.Y][cur.X].N = WALL_DOWN<br /> maze[nxt.Y][nxt.X].S = WALL_DOWN<br /> elif cur.X < nxt.X and cur.E != WALL_FIXED:<br /> print("removeWall 3") <br /> maze[cur.Y][cur.X].E = WALL_DOWN<br /> maze[nxt.Y][nxt.X].W = WALL_DOWN<br /> elif cur.X > nxt.X and cur.W != WALL_FIXED:<br /> print("removeWall 4") <br /> maze[cur.Y][cur.X].W = WALL_DOWN<br /> maze[nxt.Y][nxt.X].E = WALL_DOWN <br /> else:<br /> print("removeWall 5") </span><br />
<span style="font-family: "Courier New", Courier, monospace;">maze = createmaze(mazeWidth, mazeLength)</span><br />
<span style="font-family: "Courier New", Courier, monospace;">theStack = []</span><br />
<span style="font-family: "Courier New", Courier, monospace;">current = maze[0][0] # choose initial<br />theStack.append(current) # push current</span><br />
<span style="font-family: "Courier New", Courier, monospace;"># choose unvisited neighbor, pop if none found<br />next = chooseUnvisited()<br />next.visited = True<br />print("Next "+str(next.X)+" "+str(next.Y))<br />while len(theStack) > 0:<br /> while next == current and len(theStack) > 0:<br /> current = theStack.pop()<br /> next = chooseUnvisited()<br /> next.visited = True<br /> print("Next "+str(next.X)+" "+str(next.Y))<br /> <br /> removeWall(current, next)<br /> <br /> current = next<br /> next = chooseUnvisited()<br /> next.visited = True<br /> if next != current:<br /> theStack.append(current) <br /> <br />drawMaze()</span>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-37781923903177330712019-05-14T09:22:00.000-05:002019-05-14T09:22:01.473-05:00Advantage of Python over Java<span class="drop-caps">H</span>ere's a question for you: what is the advantage of using Python over Java? Because of the recent publication of the second edition of <a href="https://www.amazon.com/Extending-Art-Illusion-Scripting-Artists/dp/1612950035/" target="_blank">Extending Art of Illusion</a> I've been spending time working on scripts for Art of Illusion. Straight out of the box, Art of Illusion provides scripting capability for Groovy and BeanShell. This makes sense because Art of Illusion is written in Java and both of these scripting languages are based on Java. But most other graphics programs use some variation on Python as their scripting language. In a post on <a href="https://timothyfish.blogspot.com/2019/05/python-scripts-in-art-of-illusion.html" target="_blank">Python Scripts in Art of Illusion</a> I wrote about creating a plugin that adds Python to the languages that Art of Illusion supports. I use Python for things I do in my day job mostly because it's available. But with adding it to Art of Illusion I have a direct comparison between Java and Python. It got me thinking. Is there some reason to choose to script in Python rather than using Java, Groovy, or BeanShell?<br />
<br /><br />
When I setup the interpreter, I did my best to provide consistency between what can be done with Python and what can be done with Groovy. The types of scripts are the same. The editor windows are the same. The libraries linked in from Art of Illusion are the same. I'm using the Jython interpreter, so everything that can be called from a Java class can be called from Python. So, in considering the question it really does come down to language differences.<br />
<br /><br />
Groovy and Python handle blocks differently. Java is very similar to C, so a block is whatever is within curly braces. In Python blocks are handled by indenting. There's nothing particularly advantageous for one over the other. It is personal preference. Personally, I've fine with both. Comments are also handled differently. Groovy uses C++ style comments while Python uses # to mark a comment. Again, that's just personal preference. Strings are handled by both and what you can do with strings is very similar. <br />
<br /><br />
The biggest difference between Python and Java is that Python has powerful list processing capability built right in while Java treats it as more of an afterthought. Given that 3D graphics scenes are lists of objects and objects are lists of polygons and polygons are lists of vertices, how a scripting language processes lists is important. In Python, a list is denoted by square brackets, []. In Art of Illusion we're most likely to get a list by using values returned from some Java function. In addition to lists, Python has dictionaries (square brackets {}), which are an unordered table that maps keys to values. It also has sets, which are unordered collections of unique objects.<br />
<br /><br />
A list might simply be every object in the scene or every object of a certain type and we want to perform some operation on each of the objects in the list. We might use a dictionary if we want to refer to objects by name. Sets are only truly useful in combination. We might have a set of edge vertices and a set of interior vertices. We might have a set of visible vertices and a set of invisible vertices. If we wanted to perform some operation on all of the visible edge vertices then we could get the intersection of the edge vertices set and the visible set and then loop through that set rather than having a check in our loop for whether a set of conditions is met. Of course, it is possible to do this with Java as well, but having it inherent in the language is nice.Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-58802531975293526432019-05-12T17:48:00.001-05:002019-05-12T21:08:18.513-05:00Python Scripts in Art of Illusion<span class="drop-caps">I</span> took a break from the cloth simulator to look at adding Python as a scripting language for Art of Illusion. I had some success at pulling in the Jython library and was able to get the following Tool Script to add a Cube to the scene:<br />
<br />
<div>
<span style="color: black; font-family: "courier new" , "courier" , monospace; font-size: normal;">undo = UndoRecord(window, True)</span></div>
<div>
<span style="color: black; font-family: "courier new" , "courier" , monospace; font-size: normal;">obj = Cube(1.0, 1.0, 1.0)<br />
objInfo = ObjectInfo(obj, CoordinateSystem(), "Cube "+str(1))</span></div>
<div>
<span style="color: black; font-family: "courier new" , "courier" , monospace; font-size: normal;">window.addObject(objInfo, undo)</span></div>
<div>
<span style="color: black; font-family: "courier new" , "courier" , monospace; font-size: normal;">window.updateImage()</span></div>
<div>
<span style="color: black; font-family: "courier new" , "courier" , monospace; font-size: normal;">window.setUndoRecord(undo)</span></div>
<br />
<br />
In a video I demonstrated that a Groovy script could be used to<a href="https://youtu.be/Q4KZI6Kg124"> add a Cube to the scene</a>. The Groovy script was as follows:<br />
<br />
<div>
<span style="color: black; font-family: "courier new" , "courier" , monospace; font-size: normal;">undo = new UndoRecord(window, true);</span><br />
<span style="color: black; font-family: "courier new" , "courier" , monospace; font-size: normal;">obj = new Cube(1.0, 1.0, 1.0);<br />
objInfo = new ObjectInfo(obj, new CoordinateSystem(), "Cube "+1);</span><br />
<span style="color: black; font-family: "courier new" , "courier" , monospace; font-size: normal;">window.addObject(objInfo, undo); <br />
window.updateImage();<br />
window.setUndoRecord(undo);</span></div>
<br />
As you can tell, the code is essentially the same except Python doesn't use the <i><b>new</b></i> keyword, True is capitalized in Python, and Python won't concatenate an integer to a string without a conversion function. I'm sure there will be more noticeable differences once I start using it along with the language features of Python, but this was just a proof of concept.<br />
<br />
Unfortunately, I've been less successful at implementing the code required to use Python to create a Scripted Object in Art of Illusion. It might be easier if I were modifying the Art of Illusion code rather than trying to do this as a plugin, but I keep running into one typecasting issue or another. I had hoped that I might use this as the vehicle to demonstrate the value of the reference material at the back of <i>Extending Art of Illusion</i>. I can say that I've had the book open to that material the whole time I've been working on this and I have put it to good use. I can also say that I'm very glad this book is <a href="http://www.lulu.com/shop/timothy-fish/extending-art-of-illusion/hardcover/product-24096535.html">available in hardback</a>. It costs a little extra, but being able to open it and leave it open makes a world of difference.<br />
<br />
UPDATE: After writing this I found a way to get it working for Scripted Objects. I put it in a repository at <span style="background-color: transparent; color: #24292e; display: inline; float: none; font-family: , "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 12px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre; word-spacing: 0px;"><a href="https://github.com/TimothyFish/AOI_with_python.git">https://github.com/TimothyFish/AOI_with_python.git</a> </span>so I wouldn't lose what I had working. It's not ready for general use, but it is working. To use it, you will need to have the Jython.jar file in your class path for Art of Illusion. If you know what that means then have fun. If not then it's probably better that you don't mess with it. I would explain it but I only just got it working myself and I don't know that I can give you a clean cut set of instructions yet.<br />
<br />
For anyone who is interested, the following is the Python version of the Axis script that is in <i>Extending Art of Illusion</i>:<br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">from artofillusion.script import ScriptedObject</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">scene = theScript.getScene()<br />
count = 0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">length = 5.0<br />
size = 0.01</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">def createAxis(length, diameter):<br />
axis = Cylinder(length, diameter, diameter, 1.0)<br />
return ObjectInfo(axis, CoordinateSystem(), "")<br />
<br />
obj = createAxis(length, size)<br />
if not obj is None:<br />
theScript.addObject(obj)<br />
<br />
obj = createAxis(length, size)<br />
obj.getCoords().setOrientation(90.0, 0.0, 0.0)<br />
if not obj is None:<br />
theScript.addObject(obj)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">obj = createAxis(length, size)<br />
obj.getCoords().setOrientation(0.0, 0.0, 90.0)<br />
if not obj is None:<br />
theScript.addObject(obj)</span><br />
<br />
You may notice that I'm using "theScript" here instead of "script". This is because there is a conflict between "script" and "artofillusion.script" with Jython interprets the code.Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-77959777375627085552019-05-10T13:40:00.000-05:002019-05-10T13:40:02.887-05:00Art of Illusion Examples<span class="drop-caps">F</span>or each of the first ten chapters of <i>Extending Art of Illusion</i> I have created a video that demonstrates some aspect of it. One of the things I found when writing the book was that it is difficult to demonstrate animation on the printed page. In <a href="https://youtu.be/hf0RrtUPq-I">chapter 7</a> I give code for a tracker object that will rotate an object or objects so that the object is always pointing at one of the other scene objects, no matter where it is located in the scene. In the book I tried to show this with a sequence of still images taken from the animation. But in the <a href="https://youtu.be/hf0RrtUPq-I">video</a> I have been able to show the video of a head with eyes that follow an object as it moves around the scene. Not only that, but it is possible to show that these changes are occurring even as the scene is being edited.<br />
<br />
Below is the list of videos:<br />
<br />
<a href="https://youtu.be/Q4KZI6Kg124">Chapter 1: Use a Script to Add a Cube to Art of Illusion</a><br />
<a href="https://youtu.be/DCOHNRz8fx0">Chapter 2: Storing and Loading</a><br />
<a href="https://youtu.be/OfLJplMIsMM">Chapter 3: Position Objects on Floor</a><br />
<a href="https://youtu.be/p-q4RaFUUbM">Chapter 4: Point at Objects</a><br />
<a href="https://youtu.be/uuQo4rxnCXo">Chapter 5: Resting One Object on Another</a><br />
<a href="https://youtu.be/4yADpFRMzVc">Chapter 6: Adding Custom Objects</a><br />
<a href="https://youtu.be/hf0RrtUPq-I">Chapter 7: Tracking Movement</a><br />
<a href="https://youtu.be/FFg3SxJ2QGk">Chapter 8: Procedural Modules</a><br />
<a href="https://youtu.be/QUhm7Hk8q0g">Chapter 9: The Room</a><br />
<a href="https://youtu.be/AW0OKEGkJow">Chapter 10: Modeling Cloth in Art of Illusion</a>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-33381199757962474662019-04-29T21:32:00.000-05:002019-04-29T22:32:25.750-05:00Why Buy My Book About Scripts and Plugins<span class="drop-caps">A</span>fter the second edition of<i> <a href="http://www.amazon.com/Extending-Art-Illusion-Reference-Creating/dp/1612950035" target="_blank">Extending Art of Illusion</a></i> went to press my attention turned once again to the question of getting it into the hands of readers. Outside of people called Mom, people don't generally buy books just because someone wrote it. I've purchased a few books just because I knew the author, but I don't buy second and third books "just because." Those of us who love books need a reason to buy a book. No, that's not right. We want a reason to buy a book. We are begging authors and publishers to give us a reason to buy a book. We want to see a book and say, "If I buy this book this is the knowledge I will gain or the story I will enjoy." We are cheering for authors to provide us with a good book. It's in that context that I make the case for people to buy the latest edition of<i> Extending Art of Illusion</i>.<br />
<i></i><br />
I stopped to ask myself why anyone would need this book. It may seem like it is a little late to be asking that question. Over 550 pages into a project and with it already coming off the press is not the time to be asking whether it is worth doing, but there's something a little odd about doing a second edition of a book. On this edition, my focus was on very specific aspects of the book rather than on the project as a whole. It was important to me to update the reference material at the back of the book so that it matches the current release of Art of Illusion. But a higher priority than that was the cloth simulator described in Chapter 10. I have this urge to tell people that they should buy the book because it provides a cloth simulation for Art of Illusion, but the cloth simulator isn't a reason to buy the book. It is a reason to install the plugin, but it isn't a reason to buy the book.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQzLauaeOwG2MYOW6wYKRoEnMnvJEGkvq485EGZyLEPtawY9xRL0fifQomUT-Eur-ph_i9y7oWiH6s_EKNUS60i98ZO7FYWla8x4wTZfkg2qlape2pT-Vyttk7ekI5cki5hLHncz2pUQ/s1600/LotsOfBallUpClose.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a>As I thought about that, I wrote a script that I thought might help illustrate w<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQzLauaeOwG2MYOW6wYKRoEnMnvJEGkvq485EGZyLEPtawY9xRL0fifQomUT-Eur-ph_i9y7oWiH6s_EKNUS60i98ZO7FYWla8x4wTZfkg2qlape2pT-Vyttk7ekI5cki5hLHncz2pUQ/s1600/LotsOfBallUpClose.png" imageanchor="1" style="-webkit-text-stroke-width: 0px; background-color: transparent; clear: right; color: #0066cc; float: right; font-family: Times New Roman; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 16px; margin-left: 16px; orphans: 2; text-align: center; text-decoration: underline; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><img border="0" data-original-height="960" data-original-width="1280" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQzLauaeOwG2MYOW6wYKRoEnMnvJEGkvq485EGZyLEPtawY9xRL0fifQomUT-Eur-ph_i9y7oWiH6s_EKNUS60i98ZO7FYWla8x4wTZfkg2qlape2pT-Vyttk7ekI5cki5hLHncz2pUQ/s400/LotsOfBallUpClose.png" style="cursor: move;" width="400" /></a>hy people need to write scripts and plugins for Art of Illusion. If they understand that then it is easier to make the case for them to buy a book that will teach them how to write scripts and plugins.<br />
<br />
The picture to the right is one of the images that I rendered from that script. The script adds 1000 sphere to the scene. Adding 1000 of anything isn't something you would want to do by hand. Not only would it take a long time but it would be impossible to get all of the positions exactly right. With a script you can let the computer do the heavy lifting. The Groovy script I used is below:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">size = 0.2;<br />spacing = 4.0*size;<br />t = script.getTime();<br />maxTime = 10.0;<br />timeDelta = maxTime/1000.0;<br />myTime = 0.0;</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">for(k = 0; k < 10; k++){<br /> for(j = 0; j < 10; j++){<br /> for(i = 0; i < 10; i++){<br /> myTime += timeDelta;<br /> if(myTime > t) break;<br /> S = new Sphere(size, size, size);<br /> infoS = new ObjectInfo(S, new CoordinateSystem(), "Sphere");<br /> infoS.coords.setOrigin(new Vec3(spacing*(i-5.5), spacing*(j-5.5), spacing*(k-5.5)));<br /> script.addObject(infoS);<br /> }<br /> if(myTime > t) break;<br /> }<br /> if(myTime > t) break;<br />}</span><br />
<br />
You would place this script in a Scripted Object. The code is simple enough, but how would you change it if you wanted to use Cubes instead of Spheres? What if you wanted the objects spinning or pointing at the same thing? Imagine a thousand eyeballs looking at the camera. How would you achieve that? This is why people who want to do scripting in Art of Illusion need the book. Not only does it provide plenty of examples but it provides a listing of every public interface in Art of Illusion. My name is on the cover and yet I found myself reaching for this book as I was writing this script. I could have looked up the functions I needed in the source code, but I found it preferable to have the book open in front of me. And it is my belief that if you are writing scripts for Art of Illusion you will find that beneficial as well.<br />
<br />
You can buy the paperback from <a href="http://www.amazon.com/Extending-Art-Illusion-Reference-Creating/dp/1612950035">Amazon.com</a>.<br />
There is also a <a href="http://www.lulu.com/shop/timothy-fish/extending-art-of-illusion/hardcover/product-24080054.html">hardback version</a> available.Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-55411036839681928402019-03-28T22:17:00.000-05:002019-03-28T22:17:21.357-05:00Is Freewill a Myth?<p><span class="drop-caps">R</span>obots don’t sin. Of course we’ve all seen movies where some robot makes decisions concerning right and wrong, but the reality is that robots just run programs. The brain of a robot is nothing more than a device that reads data and writes data. It’s actions are controlled by what that data tells it to do. Robots don’t have a soul. If a robot does something that it shouldn’t do, we may shut it down. We may repair it. We may throw it in the landfill. But we don’t do that out of a sense of justice. If there is anyone held responsible for the evil done by a robot it is the designer, the programmer, or the operator, not the robot.</p><p>Robots don’t sin because they have no capability to decide to go against their programming. But if the inability to decide to go against their programming keeps a robot from sin then that implies that anything that can sin can decide to go against their programming. I mention this because I recently heard someone claim that “freewill is a myth.” Their basis for this claim was Ephesian 1:4 which includes the statement “he chose us in him before the foundation of the world.” Their claim was that this selection could not be based on foreknowledge of what we would do. This quickly degrades into circular reasoning. If we have no freewill then everything we do is the predetermined will of God. But if we are only doing what God said to do then we are not sinners. Even if we reject Jesus that is the will of God. Without freewill we are nothing more than moist robots and robots don’t sin.</p><p>Many people have this image of God prior to creating the world sitting there and picking people. “I’m going to save this one, but not that one…” When he is finished he creates a world ideal for the salvation of those people. The problem with this is that it implies that God’s nature is finite. If it is correct that God has always known everything that is knowable then there has never been a time when God didn’t know who would be saved and who would be lost. It’s possible that is what Paul was saying. In this light it lends support to the verses around it that talk about us being blessed with all blessings and being predestined. Predestination doesn’t make sense without foreknowledge, but there is nothing about predestination that precludes freewill.</p><p>Let’s lay aside the issue of sin for moment. Another thing that robots don’t do is love. Love does not exist without freewill. Imagine if your spouse had this button. Anytime you started feeling like she didn’t love you you could just push that button and she would instantly begin showering you with love. Is that love? Of course not. Love can only come from someone who has the choice not to love. For God to have people who loved him he had to create a world in which people could choose not to love him. This is not the violation of his sovereignty that some would suggest but he delegated to us the freedom to choose.</p><p>I see a couple of possibilities one is that God looked at the people throughout time and saw certain one’s who would believe and who would love him. These were not perfect people, but people whiling to be shaped by him into the kind of people he wanted to spend time with and these were the people he chose. The other is that he arbitrarily picked some people and over time has been shaping them to be the kind of people he wants them to be. To me, the first option is one in which human beings all have innate value even if they ultimately choose to reject him. With the second option only those he has chosen have value and the rest are simply here to live out their lives and go to hell. </p><p>I believe God has given us freewill because he wants us to be able to love him. We are not robots. If we were, then we could not sin and it would be unjust for us to be punished for our sin. If God is love and God is just then freewill is not a myth.</p>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-65298826091267223052018-10-09T09:24:00.000-05:002018-10-09T09:24:15.892-05:0012 Things Republicans and Democrats Agree On<span class="drop-caps">P</span>olitics in America according to social media is nasty. We’re divided along party lines and there are a lot of angry people yelling at each other. You would think that there’s no way to bridge the divide, but all of us have friends who are on the other side. We may avoid certain conversations when we are with them, but somehow we get along. Why? If the other side is so bad, then how is it that our friends can’t see that? Could it be that the two sides agree on much more than they care to admit? Here are twelve things that Republicans and Democrats agree on.<br />
<br />
<ol><li>Mass murder is evil.</li>
<li>A strong economy is good.</li>
<li>Children should be protected.</li>
<li>The strong should not be allowed to prey on the weak.</li>
<li>Cops who break the law should be prosecuted.</li>
<li>Skin color doesn’t make one person better than another.</li>
<li>Protecting our environment is important.</li>
<li>Non-citizen criminals should not be allowed into our country.</li>
<li>Individuals should be able to express their opinion.</li>
<li>The police have a responsibility to protect us.</li>
<li>Teachers are important.</li>
<li>People who work should be paid fairly.</li>
</ol>I can already hear you thinking, “Yeah, but…” and it’s for that reason that I’ve left these unexplained. I challenge you to lay this list down beside the political platform of any candidate on either side and see how many you can find that they don’t agree with. Ask your friends if they agree with these. Don’t ask for an explanation, just yes or no, do they agree with these or not?<br />
<br />
These are not unimportant issues. These are among the most important if not the most important issues that exist in our political debate. If we agree on the most important things then why are we so divided?<br />
<br />
It goes something like this: I and my opponent have a common goal, but we disagree on how to achieve it. I can’t see how what my opponent wants to do will achieve the goal, so I assume that my opponent doesn’t want to achieve the same goal as me. Since my opponent doesn’t support what any good person would support then my opponent must be evil. Since my opponent is evil, no one should listen to what my opponent has to say. If they do then they are also evil.<br />
<br />
A better approach is this: My opponent advocates something that I believe harms something good. I assume that my opponent doesn’t want to harm this thing, so my opponent either placed a greater priority on some other good thing or doesn’t have enough information to see how his position will do harm. Or it could be that I don’t have all of the information I need.<br />
<br />
Given that we’re dealing with individuals, it’s quite possible that the person in question is acting out of evil intentions, but the general case is that those who disagree with us believe they are fighting the good fight. They believe they are fighting to protect the children or putting an end to mass murder or fighting for the oppressed. Telling them they are not (no matter how certain we are) will only make them angry. Instead, we should try to find out what it is they are fighting for. It is probably one of the twelve things in the list above. From there, we can try to show them a better way to achieve what they are trying to achieve. And the good thing is that it probably something that we also want to achieve.Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-72397387165286303112018-09-06T05:43:00.002-05:002019-04-29T21:50:42.545-05:00Still Making Plugins and Scripts Work with Art of Illusion<i></i><br />
<blockquote class="tr_bq">
<b>Update:</b> <i>I'm happy to say that after writing this post I made the decision to revise the book and it is now available for purchase. In the process, I developed a cloth simulator plugin for Art of Illusion. I include it as part of the book as an example of a use of Art of Illusion Distortions.</i></blockquote>
<br />
<br />
<span class="drop-caps">W</span>hen a reader of Extending Art of Illusion contacted me about the possibility of updating the Art of Illusion scripts to Groovy, I became concerned. Firstly, because he wasn’t able to download the source code from the location specified in the book. Broken links on a webpage are one thing, but broken links in a book can be costly. Secondly, because I haven’t attempted to keep up with all of the changes to Art of Illusion that have taken place since the publication date of the book. There hasn’t been enough demand for the book to justify a revised edition. To address my concerns, I went back through the examples I included in the book—rebuilding with latest Java compiler and using Art of Illusion 3.03. With joy I’m able to say that they all still work. In spite of the book being seven years old, it remains useful anyone who is looking for instruction on how to create plugins for Art of Illusion.<br />
I did find a couple of things that I would add to the book if I were to revise it. The first is that to use the examples you need to include the Bouy.jar in the list of linked libraries. I’m not sure if this is a result of a change or of an oversight on my part. The second is that I would include scripts written in Groovy in the book. I’ve somewhat corrected this by adding Groovy scripts to the .zip file that contains the examples. At this point, Art of Illusion still support BeanShell even as it is moving toward Groovy, so it is really up to the person writing the script to decide which one they want to use. There are a lot more similarities between BeanShell and Groovy than there are differences, so the only change I made to the axes script was to change the file extension from .bsh to .groovy<br />
There were more differences with the Room script. At line 18 I removed the “private” specifier for the class. At line 105 I deleted “LayoutWindow layout”. At line 106 I removed the “final String” specifier because Groovy couldn’t see windowTitle as a global variable. And at line 116 I deleted “int roomCount = 0”. At 128 I rewrote the declaration as:<br />
<blockquote>
<span style="font-family: "courier new" , "courier" , monospace;"> float[] roomSmoothness;<br />
roomSmoothness = [0.0f, 0.0f, 0.0f, 0.0f];<br />
</span></blockquote>
Overall, it wasn’t difficult to make the changes, but it did take some effort and a little research to figure out the differences between the two scripting languages. <br />
<br />Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com1tag:blogger.com,1999:blog-8275104442398599121.post-49683706604249365342018-09-03T16:08:00.001-05:002018-09-03T16:08:19.248-05:00Using C++ Resource Files with Eclipse<p><span class="drop-caps">U</span>sing a resource file in Eclipse is possible. While writing a blog about <a href="http://timothyfish.blogspot.com/2018/09/developing-windows-programs-using.html">how to develop Windows programs using Eclipse and C++</a> I ran into a problem that I needed a tool for, namely to quote C++ code in the blog. So, I wrote a little program in C++ using the techniques I was discussing, but later I decided it would be an ideal project to rewrite using a resource file (.rc). There are a few things you have to do to get it to work.</p><p>First, Eclipse doesn’t provide the slick resource file editor that you find in Visual C++. This means that to edit the .rc file you will need to use a text editor. This isn’t particularly hard to do, but I did find myself questioning whether I was gaining anything by using the resource file over just making the calls I needed in the C++ code. One thing that I can say that I don’t like is that you must use #define in the header file rather than defining constants with <b>static const</b> or as an <b>enum</b>.</p><p>Second, the .rc file has to be compiled using a special compiler and then you have to link to the .o that is generated. In order to prevent yourself from having to remember to do that each time you modify the .rc file, you must create a pre-build step. Even then, changes to the .rc file won’t compile and link unless you’ve mode changes to the C++ source code. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh76sFSE3hlA-0UuKPGBOU0ZVLrK8WoKKqCH_2OW4YrzNEU_4qGfWof4SG38ubhbBH72I4pWdKmcTOY5tmPKAAS9MKp9n70NDQEzRyKvHlZwBclZwMNE1TV2Mv04D-4RGOkPDdUlyaAQw/s1600/14.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh76sFSE3hlA-0UuKPGBOU0ZVLrK8WoKKqCH_2OW4YrzNEU_4qGfWof4SG38ubhbBH72I4pWdKmcTOY5tmPKAAS9MKp9n70NDQEzRyKvHlZwBclZwMNE1TV2Mv04D-4RGOkPDdUlyaAQw/s320/14.png" width="232" height="320" data-original-width="602" data-original-height="832" /></a></div><p>As with the other blog post, you can download the Eclipse project for this program. It isn’t cleaned up, but it should provide you with an example of how to compile a resource file using Eclipse and MinGW. The command to run the winres must be supplied to Eclipse via the settings window of the C/C++ Build properties.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh34kHXJUxiSYaf8T5Ph4BjZrBgnpj8YHnskFCi-UYIyembRTam89etoZhgcskkVaLml1t-fPXGs_cZgO9r2BAiLAQJwek42JqLGslyVTUBXxTUGfdHuIdZBfhkmD49mSUtPrTQgycFNw/s1600/15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh34kHXJUxiSYaf8T5Ph4BjZrBgnpj8YHnskFCi-UYIyembRTam89etoZhgcskkVaLml1t-fPXGs_cZgO9r2BAiLAQJwek42JqLGslyVTUBXxTUGfdHuIdZBfhkmD49mSUtPrTQgycFNw/s400/15.png" width="384" height="400" data-original-width="821" data-original-height="855" /></a></div><p>This command is:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">c:\mingw\bin\windres.exe --include-dir="${ProjDirPath}" --input="${ProjDirPath}/res.rc" --output="${ProjDirPath}/res.o" --define RESLOC="${ProjDirPath}/resources.h"</span></blockquote><p>Notice that I provide the project directory path for both the input and the output. For some reason, MinGW doesn’t seem to recognize –include-dir, but I populate it anyway. I also define a macro RESLOC. You will see this used within the .rc file where we include resources.h, since winres can’t find the local directory on its path.</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">#define Q(x) #x<br />
#define QUOTE(x) Q(x)<br />
#include QUOTE(RESLOC)<br />
<br />
#define APSTUDIO_HIDDEN_SYMBOLS<br />
#include "windows.h"<br />
#undef APSTUDIO_HIDDEN_SYMBOLS</span></blockquote><br />
<p>The rest is pretty much the same as you would expect for a resource file and in many cases you can copy on that has been created with Visual Studio, if you don’t want to edit it by hand.</p><p>The Eclipse Project is located at: <a href="http://www.timothyfish.com/Examples/Windows4Eclipse/BlogCodeFormat.zip">http://www.timothyfish.com/Examples/Windows4Eclipse/BlogCodeFormat.zip</a></p>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-61561313235050571712018-09-02T23:28:00.000-05:002018-09-02T23:28:09.200-05:00Developing Windows Programs using Eclipse C++<p><a href="https://wiki.eclipse.org/CDT"><span class="drop-caps">E</span>clipse CDT (C/C++ Development Toolkit)</a> is perfectly fine for developing Windows applications in C++. But you might be asking, why would I want to do that when Visual Studio is so readily available?</p><p>I started down this path because I spend most of my time with the Eclipse IDE (Integrated Development Environment) running on my machine and often with multiple workspaces on both Windows and Linux, but the C++ code I develop isn’t intended to run on Windows. But ever so often I will develop a simple tool with a Graphical User Interface (GUI). Since I’m familiar with Eclipse, I would prefer not to have to switch to another IDE just for a simple tool. But one thing you notice when you look at an IDE like Visual Studio is that it generates a significant amount of code for you and it makes use of various libraries, but how much of this do you really need?</p><p>I assume you’ve built with the Eclipse CDT. If not, follow this guide first:<br />
<a href="https://www.codeproject.com/Articles/14222/C-Development-using-eclipse-IDE-Starters-guide">https://www.codeproject.com/Articles/14222/C-Development-using-eclipse-IDE-Starters-guide</a></p><p>Also, if you want to skip ahead, the source projects are located in the following locations:</p><p><a href="http://www.timothyfish.com/Examples/Windows4Eclipse/HelloMsg.zip">http://www.timothyfish.com/Examples/Windows4Eclipse/HelloMsg.zip</a></p><p><a href="http://www.timothyfish.com/Examples/Windows4Eclipse/ExampleWin.zip">http://www.timothyfish.com/Examples/Windows4Eclipse/ExampleWin.zip</a></p><p>I started down this path because I spend most of my time with the Eclipse IDE (Integrated Development Environment) running on my machine and often with multiple workspaces on both Windows and Linux, but the C++ code I develop isn’t intended to run on Windows. But ever so often I will develop a simple tool with a Graphical User Interface (GUI). Since I’m familiar with Eclipse, I would prefer not to have to switch to another IDE just for a simple tool. But one thing you notice when you look at an IDE like Visual Studio is that it generates a significant amount of code for you and it makes use of various libraries, but how much of this do you really need?</p><p>One of my favorite books when I was younger was <i>Programming Windows 3.1</i> by Charles Petzold. He’s updated it as the Windows OS has moved on, but that book is still in my library. The thing that surprised me when I first read it was that just to display a simple window on the screen required two pages of C code. In the fifth edition of <i>Programming Windows</i> he has that down to a much simpler program:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">#include <windows.h><br />
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,<br />
PSTR szCmdLine, int iCmdShow)<br />
{</span><br />
<div><span style="font-family: "courier new" , "courier" , monospace;"> MessageBox (NULL, TEXT ("Hello, Windows 98!"), </span></div><div><span style="font-family: "courier new" , "courier" , monospace;"> TEXT ("HelloMsg"), 0);</span></div><span style="font-family: "courier new" , "courier" , monospace;"> return 0;<br />
}<br />
</span></blockquote><p>While that kind of program will let you test that you are able to compile and run a program from your IDE, it only hints at the more complicated nature of the Windows API (Application Programming Interface). For me, I not only wanted to know that I could write a program in Eclipse that would display a message box, but that I could use Eclipse for more useful programs as well. But I also wanted it to follow a more C++ oriented programming style. </p><p>But before we move farther, let’s compile and run a version of his C program from Eclipse. On my machine I have installed the following:<br />
<ul><li>MinGW-w64 (<a href="http://mingw-w64.org/doku.php/start">http://mingw-w64.org/doku.php/start</a>)<ul><li>installed at C:\MinGW</li></ul></li><li>Eclipse with the CDT installed (<a href="http://www.eclipse.org/cdt/">http://www.eclipse.org/cdt/</a>)</li></ul></p><p>In the Eclipse C++ Perspective, create a new C++ Project.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcvJr3hL7slWJher12EqZE-p7ekV8MpgvB4_xrZH9Ng4yhLAZdnu3bb_9_yvdJPaRDsKIBntbJlwla6SuCLp7fmaO4X5aP7lGiIKfXKBLDdQFs23jVF_fsVXa7IYp4ZSa3H-AEUfzm1g/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcvJr3hL7slWJher12EqZE-p7ekV8MpgvB4_xrZH9Ng4yhLAZdnu3bb_9_yvdJPaRDsKIBntbJlwla6SuCLp7fmaO4X5aP7lGiIKfXKBLDdQFs23jVF_fsVXa7IYp4ZSa3H-AEUfzm1g/s400/1.png" width="400" height="301" data-original-width="1017" data-original-height="765" /></a></div><p>Select C++ Managed Build and click Next.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIhI76QbtAOFLQgI1HjvmZwraU2aE44iD94sekOTyvhVrqpIfhEWrJuDKBJh7zw4ePfM4ljYHSdMI7PaYrE1J8COeCwi-Gbq5tlfllndRph_3T_wdRXwXmBLRmjsbGlRRfWdATg2xuJg/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIhI76QbtAOFLQgI1HjvmZwraU2aE44iD94sekOTyvhVrqpIfhEWrJuDKBJh7zw4ePfM4ljYHSdMI7PaYrE1J8COeCwi-Gbq5tlfllndRph_3T_wdRXwXmBLRmjsbGlRRfWdATg2xuJg/s400/2.png" width="400" height="298" data-original-width="511" data-original-height="381" /></a></div><p>Select Empty Project and give it a name. Click Next.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitIyCEqUSK1MiixwAujgta7-XZSnGnjZbB6TbrX0ul8fbMjPwUOAZggEP8KiVSs3SwxTCEciKvAc5TXqR5VjKdsrbtwbQo8Gg8-3PVNMHFx1BwJPTnJZ-RS5w1TN6OZbJau0rSa0-DhQ/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitIyCEqUSK1MiixwAujgta7-XZSnGnjZbB6TbrX0ul8fbMjPwUOAZggEP8KiVSs3SwxTCEciKvAc5TXqR5VjKdsrbtwbQo8Gg8-3PVNMHFx1BwJPTnJZ-RS5w1TN6OZbJau0rSa0-DhQ/s400/3.png" width="360" height="400" data-original-width="511" data-original-height="567" /></a></div><p>At this next window we could set some specifics, but we’ll ignore it for now. Click Finish.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4_I236P4tS6xu5QqC5CH08k1Fgdu6JUTCdyIH8ZIVSkwB8TeKWeOEMDdIbhXxRpXhAlJIa2rdfjmsYFT1hNrq_CJA4tHL8wmQLM1xYyA4359dVtomr3LOenTzKQMOqDk6ye_JQob7cw/s1600/4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4_I236P4tS6xu5QqC5CH08k1Fgdu6JUTCdyIH8ZIVSkwB8TeKWeOEMDdIbhXxRpXhAlJIa2rdfjmsYFT1hNrq_CJA4tHL8wmQLM1xYyA4359dVtomr3LOenTzKQMOqDk6ye_JQob7cw/s400/4.png" width="360" height="400" data-original-width="511" data-original-height="567" /></a></div><p>Right click on the project name and create a new file.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcNmVZV0G79MNmtZgUf3_C_AUck9_DbiAdKppFRKsjtlrib1eSBuOOdRko2fjg8mfM9-j9gV0dtySwQuuImjmdaUyJOxk5w2FxWZUdl_MB3oz6bSQHiN3j87faY8uEm2arXMbDTEpxAw/s1600/5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcNmVZV0G79MNmtZgUf3_C_AUck9_DbiAdKppFRKsjtlrib1eSBuOOdRko2fjg8mfM9-j9gV0dtySwQuuImjmdaUyJOxk5w2FxWZUdl_MB3oz6bSQHiN3j87faY8uEm2arXMbDTEpxAw/s400/5.png" width="400" height="231" data-original-width="659" data-original-height="380" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH8c7Ude7Y8K7q_tygjK0Jd3HZ-54RUm1-MoDWFgfNeMLblDpZkpn2fnGATv7yaHI6zYunonu4ryvgW4o4Kx0UulclWVdxiWcwCOHPPCl0AmquI2bTDqyfxccacr2S-JXKYv9auS82xg/s1600/6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH8c7Ude7Y8K7q_tygjK0Jd3HZ-54RUm1-MoDWFgfNeMLblDpZkpn2fnGATv7yaHI6zYunonu4ryvgW4o4Kx0UulclWVdxiWcwCOHPPCl0AmquI2bTDqyfxccacr2S-JXKYv9auS82xg/s400/6.png" width="342" height="400" data-original-width="511" data-original-height="598" /></a></div><p>Enter the following code and click the build button:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;"><br />
#include <windows.h><br />
int WINAPI WinMain (HINSTANCE hInstance, <br />
HINSTANCE hPrevInstance,<br />
PSTR szCmdLine, <br />
int iCmdShow)<br />
{<br />
MessageBox (NULL, TEXT ("Hello, World!"), <br />
TEXT ("HelloMsg"), 0);<br />
return 0;<br />
}<br />
</span></blockquote><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA5M6Ui6JO7mTXiR_t2m_e0OsjPAPnqSj8Bb0JIM9SXTixoZ_mHCdqI3qJkcRveYqYKG8Pi2SUsojt-PVVAKdmRM2UtK8EGQMtv9CrI4ZcemUDKqcQYgA4s1JCm1IHwaOKRFr_hst3NA/s1600/7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA5M6Ui6JO7mTXiR_t2m_e0OsjPAPnqSj8Bb0JIM9SXTixoZ_mHCdqI3qJkcRveYqYKG8Pi2SUsojt-PVVAKdmRM2UtK8EGQMtv9CrI4ZcemUDKqcQYgA4s1JCm1IHwaOKRFr_hst3NA/s400/7.png" width="400" height="301" data-original-width="1010" data-original-height="761" /></a></div><p>If everything is installed correctly then this program should build, and you should be able to run it by clicking the Run Button. This will display something like the following:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNoA0XQd3HmgAgfSU29cbKG6petEBx2moOYgGLoIyGgMsxLN7_ytPTPDZPou9_kFIWZb-rFhbdWWDeLZtMlEMXLV17O658GQok3q9vCe0IWeW3Pt8aHidQ-YbJvmheNybXfllg8dSpmw/s1600/8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNoA0XQd3HmgAgfSU29cbKG6petEBx2moOYgGLoIyGgMsxLN7_ytPTPDZPou9_kFIWZb-rFhbdWWDeLZtMlEMXLV17O658GQok3q9vCe0IWeW3Pt8aHidQ-YbJvmheNybXfllg8dSpmw/s1600/8.png" data-original-width="119" data-original-height="128" /></a></div><p>But as I said before, this isn’t particularly useful other than to verify that your development environment is setup properly. What we would like to do is have a program that displays a window in which we specify what controls are used and where they are located on the page. We may even want to open another window.</p><p>Create another new project following the same steps as before. Call the project “ExampleWin” and add a file called “start.cpp” to the project.</p><p>Going back to Charles Petzold and <i>Programming Windows</i>, because he was writing in C, his WinMain consisted of a page of code that created a window and then went into a message loop. He also had one callback function WndProc that handled the WM_PAINT message by drawing text on the screen. It also handled WM_DESTROY by posting 0 to the message queue so that the loop in WinMain would terminate. We don’t see the code for it, but the MessageBox function is doing all of this in its code. So, there’s really no reason why we have to have such a long WinMain and since we’re working with C++ instead of C, we can create a class that handles it rather than just a function. We still have to put all the details somewhere, but we can keep WinMain simple. This is very useful if you are using a test environment that needs to replace WinMain with its own. It’s much easier to tell it how to replace one call than it is to tell it how to replace a page of code.</p><p>The code for start.cpp should look like this:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">// *<br />
// * StartApp.h<br />
// *<br />
// * Created on: Sep 1, 2018<br />
// * Author: Timothy Fish<br />
// * Website: http://www.timothyfish.com<br />
// *<br />
<br />
#ifndef STARTAPP_H_<br />
#define STARTAPP_H_<br />
#include <windows.h><br />
<br />
class StartApp {<br />
public:<br />
static StartApp& getInstance();<br />
virtual ~StartApp();<br />
<br />
int begin(HINSTANCE hInstance,<br />
HINSTANCE hPrevInstance,<br />
PSTR lpCmdLine,<br />
int nCmdShow);<br />
<br />
HINSTANCE getHInstance(){ return hInst; }<br />
void setHInstance(HINSTANCE h){ hInst = h; }<br />
private:<br />
static StartApp* instance;<br />
bool running;<br />
<br />
HINSTANCE hInst;<br />
const char* className = "StartApp";<br />
const char* appName = "Example Windows App";<br />
StartApp();<br />
};<br />
<br />
#endif /* STARTAPP_H_ */<br />
</span></blockquote><p></p><p>Click the build button and you should expect to see the following error:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">..\start.cpp:2:10: fatal error: StartApp.h: No such file or directory<br />
#include <StartApp.h><br />
^~~~~~~~~~~~<br />
<br />
</span></blockquote><p>This is telling us that it doesn’t know where StartApp.h is. You could put it into quotes, but since some coding standards tell us not to do that sort of thing, let’s add the source directory to the include directories. To do that, Right click on the ExampleWin project name and select <i>properties</i>. Select C/C++ General and go to the Includes tab. Add <b>${ProjDirPath}</b> to the GNU C++ Language all configurations. (You may add it to the other languages if you like, but we’re only using C++ here. Apply and close.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVC0UuxjW1h0qdnG98gEDiEhz0Vm_j7OxRcm8nVSvvQb3rJMPlm0-bSAM_9Pcke_e-5PjM_oni-OjV3qwtPPw57KPbTIyB0H0w1o7Rj7foIC2XpUvQ3OoFwkqJ1y4bV35ZcRJ9BdwD4g/s1600/9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVC0UuxjW1h0qdnG98gEDiEhz0Vm_j7OxRcm8nVSvvQb3rJMPlm0-bSAM_9Pcke_e-5PjM_oni-OjV3qwtPPw57KPbTIyB0H0w1o7Rj7foIC2XpUvQ3OoFwkqJ1y4bV35ZcRJ9BdwD4g/s400/9.png" width="400" height="274" data-original-width="821" data-original-height="562" /></a></div><p>Now when you build you should get the following errors:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">start.o: In function `WinMain@16':<br />
C:\Users\timot\Eclipse4Windows\ExampleWin\Debug/../start.cpp:9: undefined reference to `StartApp::getInstance()'<br />
C:\Users\timot\Eclipse4Windows\ExampleWin\Debug/../start.cpp:9: undefined reference to `StartApp::begin(HINSTANCE__*, HINSTANCE__*, char*, int)'<br />
collect2.exe: error: ld returned 1 exit status<br />
</span></blockquote><p>These are both linker errors. They exist because we haven’t added the functions to the StartApp.cpp file yet. To do this, create another new file StartApp.cpp and add the following code:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">// *<br />
// * StartApp.cpp<br />
// *<br />
// * Created on: Sep 1, 2018<br />
// * Author: Timothy Fish<br />
// * Website: http://www.timothyfish.com<br />
// *<br />
<br />
#include <StartApp.h><br />
<br />
#include <iostream><br />
#include <windows.h><br />
#include <windowsx.h><br />
<br />
StartApp* StartApp::instance = 0;<br />
<br />
StartApp& StartApp::getInstance(){<br />
<br />
if(instance == 0){<br />
instance = new StartApp();<br />
}<br />
<br />
return *instance;<br />
}<br />
<br />
StartApp::StartApp(): running(0), hInst(0) {<br />
}<br />
<br />
StartApp::~StartApp() {<br />
}<br />
<br />
int StartApp::begin(HINSTANCE hInstance,<br />
HINSTANCE hPrevInstance,<br />
PSTR lpCmdLine,<br />
int nCmdShow)<br />
{<br />
return 0;<br />
}<br />
<br />
</span></blockquote><p>Another thing that I would recommend doing at this point is add static linking of gcc by adding the following to you link command: <b>-static -static-libgcc -static-libgcc</b>. This will save you having to find the dll to run outside of Eclipse.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ4Zy_T2ZAB1Sim708xw88b1301H-8LIB3ciUsl0brZfsdOREbLq9XomANJ-4sGZrz35ganG5iYlNgjseur8NSdBmflP0trLRl61xgkvZiTdqN-qrS902KjQ1LqAUUQMzuMz8cmL58Xw/s1600/11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ4Zy_T2ZAB1Sim708xw88b1301H-8LIB3ciUsl0brZfsdOREbLq9XomANJ-4sGZrz35ganG5iYlNgjseur8NSdBmflP0trLRl61xgkvZiTdqN-qrS902KjQ1LqAUUQMzuMz8cmL58Xw/s400/11.png" width="400" height="348" data-original-width="821" data-original-height="715" /></a></div><p>At this point, you should be able to build and run without errors. With multiple projects in Eclipse you may need to specify which one to run by selecting the project and then selecting Run As|Local C/C++ Application.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirExr8soNSU2jZbMfXB5yyybBoge8iz1equzOfYwNmnqOgAnE8jHvwLxp-tTrKX773r3HLZ00MXnKBnXfAtZblK7507_fymfXhG5lL4DHtJLHfLeDjDfFFmKN8F62_Da-Jf2ybclyKpw/s1600/10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirExr8soNSU2jZbMfXB5yyybBoge8iz1equzOfYwNmnqOgAnE8jHvwLxp-tTrKX773r3HLZ00MXnKBnXfAtZblK7507_fymfXhG5lL4DHtJLHfLeDjDfFFmKN8F62_Da-Jf2ybclyKpw/s400/10.png" width="400" height="192" data-original-width="823" data-original-height="395" /></a></div><p>If you run it at this point, it will appear that it did nothing, since we haven’t yet created a window and we don’t have a message loop. If you like, you can run it using the debugger (click the bug button) and step through the code to verify that it is actually running something. Otherwise the code will run and exit without showing you anything. To correct this, we need to modify the begin function.</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">int StartApp::begin(HINSTANCE hInstance,<br />
HINSTANCE hPrevInstance,<br />
PSTR lpCmdLine,<br />
int nCmdShow)<br />
{<br />
UNREFERENCED_PARAMETER(hPrevInstance);<br />
UNREFERENCED_PARAMETER(lpCmdLine);<br />
<br />
if(running) return 0; // only run one copy<br />
<br />
MyRegisterClass(hInstance);<br />
<br />
if (!InitInstance (hInstance, nCmdShow))<br />
{<br />
std::cout<<"Start - GetLastError - InitInstance: "<<GetLastError()<<std::endl;<br />
return FALSE;<br />
}<br />
<br />
MSG msg;<br />
<br />
while (GetMessage(&msg, nullptr, 0, 0))<br />
{<br />
TranslateMessage(&msg);<br />
DispatchMessage(&msg);<br />
}<br />
<br />
return (int) msg.wParam;<br />
}<br />
</span></blockquote><p>We are introducing some new functions here, so you will also need to modify StartApp.h to add the following as private member functions to the class:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;"> ATOM MyRegisterClass(HINSTANCE hInstance);<br />
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);<br />
static LRESULT CALLBACK WndProc(HWND hwnd, <br />
UINT message, <br />
WPARAM wParam, <br />
LPARAM lParam);<br />
</span></blockquote><p>Building at this point should result in the following errors:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">StartApp.o: In function `_::ZN8StartApp5beginEP11HINSTANCE(char *, int) static':<br />
C:\Users\timot\Eclipse4Windows\ExampleWin\Debug/../StartApp.cpp:42: undefined reference to `StartApp::MyRegisterClass(HINSTANCE__*)'<br />
C:\Users\timot\Eclipse4Windows\ExampleWin\Debug/../StartApp.cpp:44: undefined reference to `StartApp::InitInstance(HINSTANCE__*, int)'<br />
collect2.exe: error: ld returned 1 exit status<br />
</span></blockquote><p>We will implement MyRegisterClass and InitInstance in a moment, but first let’s look at begin. </p><blockquote><span style="font-family: "courier new" , "courier" , monospace;"> UNREFERENCED_PARAMETER(hPrevInstance);<br />
UNREFERENCED_PARAMETER(lpCmdLine);<br />
</span></blockquote><p>These like trick the compiler into thinking that these unused variables are actually used, so we don’t see warnings.</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">if(running) return 0; // only run one copy</span></blockquote><p>This line prevents begin from being called twice.</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;"> MSG msg;<br />
<br />
while (GetMessage(&msg, nullptr, 0, 0))<br />
{<br />
TranslateMessage(&msg);<br />
DispatchMessage(&msg);<br />
}<br />
<br />
return (int) msg.wParam;<br />
</span></blockquote><p>This code is the standard message loop for a Windows program. We retrieve the message from the queue and pass it back to Windows. We keep doing this until we GetMessage returns 0. If we need to do something special within this loop we can, but we have no need to at this point.</p><p>Add the following code to StartApp.cpp:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;">ATOM StartApp::MyRegisterClass(HINSTANCE hInstance)<br />
{<br />
WNDCLASSEX windowClass; //window class<br />
<br />
windowClass.cbSize = sizeof(WNDCLASSEX);<br />
windowClass.style = CS_HREDRAW | CS_VREDRAW;<br />
windowClass.lpfnWndProc = WndProc;<br />
windowClass.cbClsExtra = 0;<br />
windowClass.cbWndExtra = 0;<br />
windowClass.hInstance = hInstance;<br />
windowClass.hIcon = LoadIcon(0, IDI_APPLICATION);<br />
windowClass.hCursor = LoadCursor(0, IDC_ARROW);<br />
windowClass.hbrBackground = GetSysColorBrush(COLOR_WINDOW);<br />
windowClass.lpszMenuName = 0;<br />
windowClass.lpszClassName = className;<br />
windowClass.hIconSm = LoadIcon(0, IDI_WINLOGO);<br />
return RegisterClassEx(&windowClass);<br />
}<br />
<br />
BOOL StartApp::InitInstance(HINSTANCE hInstance, int nCmdShow)<br />
{<br />
hInst = hInstance; // Store instance handle in our global variable<br />
RECT windowRect;<br />
<br />
int width = 300;<br />
int height = 200;<br />
<br />
windowRect.left =(long)0; //set left value to 0<br />
windowRect.right =(long)width; //set right value to requested width<br />
windowRect.top =(long)0; //set top value to 0<br />
windowRect.bottom =(long)height;//set bottom value to requested height<br />
<br />
AdjustWindowRectEx(&windowRect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);<br />
<br />
HWND hwnd = CreateWindowEx(0, className, //class name<br />
appName, //app name<br />
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,<br />
400, 300, //x and y coords<br />
windowRect.right - windowRect.left,<br />
windowRect.bottom - windowRect.top,//width, height<br />
0, //handle to parent<br />
0, //handle to menu<br />
hInstance, //application instance<br />
0); //no xtra params<br />
<br />
if (!hwnd)<br />
{<br />
std::cout<<"Start - GetLastError - CreateWindowEx: "<<GetLastError()<<std::endl;<br />
return FALSE;<br />
}<br />
<br />
ShowWindow(hwnd, nCmdShow);<br />
UpdateWindow(hwnd);<br />
<br />
return TRUE;<br />
}<br />
<br />
LRESULT CALLBACK StartApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)<br />
{<br />
static HINSTANCE hInstance;<br />
UNREFERENCED_PARAMETER(hInstance);<br />
<br />
switch (message)<br />
{<br />
case WM_CREATE:<br />
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;<br />
break;<br />
case WM_PAINT:<br />
{<br />
PAINTSTRUCT ps;<br />
HDC hdc = BeginPaint(hwnd, &ps);<br />
UNREFERENCED_PARAMETER(hdc);<br />
// TODO: Add any drawing code that uses hdc here...<br />
<br />
EndPaint(hwnd, &ps);<br />
}<br />
break;<br />
case WM_DESTROY:<br />
PostQuitMessage(0);<br />
break;<br />
default:<br />
return DefWindowProc(hwnd, message, wParam, lParam);<br />
}<br />
return 0;<br />
}<br />
<br />
<br />
<br />
</span></blockquote><p>Now, when you Build and Run you should see a small window appear on the screen.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4G-JMoh9AnSzNerejUJTyc0vQpRFqXZRp7s5BKCM-gSevCRZw3-AelL2DzGB826NrFFhZSOdr_667o7d5z0x4HBLpctM5SJiiZrtFlz1Sm01KGdlkblJP5C5wPxckwDKQ1Ax5mKJeLA/s1600/12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4G-JMoh9AnSzNerejUJTyc0vQpRFqXZRp7s5BKCM-gSevCRZw3-AelL2DzGB826NrFFhZSOdr_667o7d5z0x4HBLpctM5SJiiZrtFlz1Sm01KGdlkblJP5C5wPxckwDKQ1Ax5mKJeLA/s1600/12.png" data-original-width="302" data-original-height="232" /></a></div><p>While this is a small success, to be useful we need it to either provide information to the user or to request information from the user. As a proof of concept, lets display an edit box that accepts a character and displays the ASCII representation of it when the user clicks the Submit button. We need to add an edit box, a static, and a button to the window. We do this by modifying the InitInstance function. Add the following code to InitInstance just before ShowWindow:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;"> CreateWindow(TEXT("edit"), TEXT("A"),<br />
WS_VISIBLE | WS_CHILD | SS_CENTER|WS_BORDER,<br />
width/2-10, 20, 20, 25,<br />
hwnd, (HMENU) IDM_CHAR, NULL, NULL);<br />
<br />
CreateWindow(TEXT("static"), TEXT("65"),<br />
WS_VISIBLE | WS_CHILD | SS_CENTER,<br />
width/2-10, 45, 20, 25,<br />
hwnd, (HMENU) IDM_INT, NULL, NULL);<br />
<br />
CreateWindow(TEXT("button"), TEXT("Submit"),<br />
WS_VISIBLE | WS_CHILD ,<br />
200, 140, 80, 25,<br />
hwnd, (HMENU) IDM_SUBMIT, NULL, NULL);<br />
</span></blockquote><p>Add the following to the private section of the StartApp class:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;"> enum ControlIds{<br />
IDM_CHAR = 100,<br />
IDM_INT,<br />
IDM_SUBMIT<br />
};<br />
</span></blockquote><p>When you run this code you should see something like the following:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrUHls__PSehjA1j-YVnOQZREWmgFb7nD-NDZhgdiQlSE3GDbGUeIpIeWEHUTMqsQd66BdXshbU7Q1DwXqNY7yo2AOQbeJ3gEiPyWTC_FP3PxsWIEXHTLxdBvVNQTsO6XXLPLXe1HTgg/s1600/13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrUHls__PSehjA1j-YVnOQZREWmgFb7nD-NDZhgdiQlSE3GDbGUeIpIeWEHUTMqsQd66BdXshbU7Q1DwXqNY7yo2AOQbeJ3gEiPyWTC_FP3PxsWIEXHTLxdBvVNQTsO6XXLPLXe1HTgg/s1600/13.png" data-original-width="302" data-original-height="232" /></a></div><p>But while it looks like we would expect, nothing happens when we click the Submit button. To correct that, we need to add some code that handles the button clicks. Add the following code to the switch statement in WndProc:</p><blockquote><span style="font-family: "courier new" , "courier" , monospace;"> case WM_COMMAND:<br />
{<br />
int wmId = LOWORD(wParam);<br />
switch (wmId)<br />
{<br />
case IDM_SUBMIT:<br />
{<br />
char buf[5];<br />
<br />
GetDlgItemText( hwnd, IDM_CHAR, buf,2 );<br />
<br />
int asciiVal = int(buf[0]);<br />
itoa(asciiVal, buf, 10);<br />
<br />
SetDlgItemText( hwnd, IDM_INT, buf );<br />
}<br />
break;<br />
default:<br />
return DefWindowProc(hwnd, message, wParam, lParam);<br />
}<br />
}<br />
break;<br />
</span></blockquote><p>Each time a button is clicked the WM_COMMAND message is sent with an Id in LOWORD(wParam). In the internal switch we check to see if that Id is IDM_SUBMIT, which is the id we gave the Submit button when we created it. When it is, we get the text from the Edit Box, which has Id IDM_CHAR, place it in buf, convert the first character to an int, then we convert that int to ASCII and place the value in buf. We set the text in the static with Id IDM_INT to the value in buf.</p><p>If you are able to do this much within the Eclipse IDE, you can do the rest by researching the specifics of the Windows API. You can download the Eclipse projects, which include the source code in this example plus some more code that implements a menu that calls an About Dialog that is implemented as a separate class.</p><p>You will notice that some of what we are doing here could be done using a resource file. I stayed away from resource files in this example because having additional files makes it harder to follow where things are coming from. To use a resource file you will need to call windres on the .rc file to generate a .o while that you can link with your program. </p><p>The source projects are located in the following locations:</p><p><a href="http://www.timothyfish.com/Examples/Windows4Eclipse/HelloMsg.zip">http://www.timothyfish.com/Examples/Windows4Eclipse/HelloMsg.zip</a></p><p><a href="http://www.timothyfish.com/Examples/Windows4Eclipse/ExampleWin.zip">http://www.timothyfish.com/Examples/Windows4Eclipse/ExampleWin.zip</a></p>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-25599313983809551132018-08-04T07:48:00.000-05:002018-08-04T07:48:13.941-05:00When God Lies<p><quote><I>So, when God desired to show more convincingly to the heirs of the promise the unchangeable character of his purpose, he guaranteed it with an oath, so that by two unchangeable things, in which it is impossible for God to lie, we who have fled for refuge might have strong encouragement to hold fast to the hope set before us.</I> – Hebrews 6:17-18(ESV)</quote></p><p><quote><I>Therefore, God sends them a strong delusion, so that they may believe what is false, in order that all may be condemned who did not believe the truth but had pleasure in unrighteousness.</I> – II Thessalonians 2:11-12(ESV)</quote></p><p><span class="drop-caps">D</span>oes God lie? The writer of Hebrews based the certainty of God’s promise on the unchangeable truth that it is impossible to lie. It’s the sort of thing you expect to see written with needlepoint and hanging on a wall next to a cross. But what about what Paul wrote to the assembly at Thessalonica? “God sends them a strong delusion.” Can they both be true? We certainly can’t write it off as a mistake because the Bible gives us multiple situations in which people were deceived as a result of an act of God. Exodus 7-9 repeatedly tells us that the Lord hardened Pharaoh’s heart. I Kings 22 and II Chronicles 18 tell a story of the Lord sending a “lying spirit” to be in the mouth of the prophets. And that doesn’t even consider the times that God blessed the lies of people like Rahab or Jael. How do we resolve this?</p><p>First, consider that we never see God utter a lie, but the deception is carried out by those sent by God. This may be because it is truly impossible for God to lie. God spoke, and the world came into being from nothing. It may be that if God were to speak a lie that the whole Universe would be torn apart trying to deal with the paradox. But that doesn’t keep him from sending messengers who are deceitful at his command or keep him from “hardening” a heart.</p><p>Next, consider the situations in which these messengers have been sent. In I Kings 22 and II Chronicles 18 the Lord sent the lying spirit to lure King Ahab out to battle so that he would fall as had be prophesied. Ahab was an evil king who didn’t want to believe the Lord. So, even when Macaiah told him that the Lord had sent a lying spirit Ahab followed the lie. And let’s look again at II Thessalonians 2:11-12. Why did God send strong delusion? Because they didn’t believe the truth and had pleasure in unrighteousness.</p><p>Can we summarize this by saying that when God lies it is because people have rejected the truth? The deception that comes from God is used to move people into a position where they will receive justice for their unrighteousness. How many times have we seen people who have done evil things and were caught because they thought they could get away with it. They believed a lie and it exposed their unrighteousness. Could it be that God sent a messenger to persuade them to believe the lie? They preferred the lie over the truth, so God gave them what they wanted.</p><p>What you might be asking is whether it is okay for us to lie. Rahab hid the spies and was blessed by God. Jael offered a man protection and then slew him while he slept, but she too was blessed by God. But Ananias and Sapphira lied about how much they were paid for their land and they died at the word of Peter. There seems to be two kinds of lies. One lie is the usual kind in which we tell something that is untrue because we desire unrighteous gain. The other kind is one in which we tell something untrue because it will prevent unrighteousness or bring about justice. An example of this might be that a gunman enters a school and asks someone where others are hiding. To say that there are no others would be a lie, but it would prevent the death of those students. Contrast this with someone telling the police that the gunman ran in the opposite direction of what he did.</p><p>It seems that a lie in and of itself may not be sin, but the evilness of the lie is determined by the evilness of the result. We must be extremely careful because it is so easy for us to convince ourselves that we are lying for good reasons and yet the results turn out otherwise. When in doubt, tell the truth, but don’t aid those who do unrighteousness. <br />
</p>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com1tag:blogger.com,1999:blog-8275104442398599121.post-89071009288376113632018-05-21T22:43:00.000-05:002018-05-21T22:43:16.716-05:00The Reason for Mass Killings and How to Prevent Mass Shootings<p><span class="drop-caps">O</span>nce more we hear the news of another mass killing. And once more we hear much talk about what we need to do to prevent it from happening again. Though there is much expressed anger on all sides I have yet to see anyone present a solution that would’ve prevented one of the recent mass killings, let alone all of them. Some people have focused on gun control, but the most recent shooting involved guns that the gun control advocates thought were safe. And then there are the killings like the New York truck attack and the Boston Marathon bombing that wouldn’t have been stopped by even the strictest gun ban. </p><p>For all the talk of what we need to do about these killings there’s been little talk about why they are taking place. How can we prevent them if we don’t know why they are happening? One person said they knew why they are happening, “It’s Satan.” I don’t disagree, but I also don’t think that answer is helpful. Even if Satan himself is whispering in the ear of each of these killers we still need to understand why they are listening to Satan. Why would they plan their attack with every intention of taking their own lives? If that’s what Satan were telling you to do, don’t you think you would say, “Get thee behind me, Satan?” </p><p>Some of these attacks are terrorist attacks and we sort of understand those, though people are still trying to figure out how these guys become radicalized so quickly. It’s quite likely that the terrorists are killing for the same reason the non-terrorists are killing, so the question of radicalization may not matter. But why are the non-terrorists killing? </p><p>The shooter in Santa Fe and the left leaning woman who hot up YouTube in San Bruno, California may give us a clearer understanding than the other killers. The kid in Santa Fe made an interesting statement when he said that he shot people he didn’t know because he wanted the people who knew him to be able to tell his story. And the YouTube shoot did what she did because she believed YouTube was preventing people from watching her YouTube channel. Neither had mainline views, and they had views that were dissimilar to each other, but the thing they had in common was that they wanted to be heard. </p><p>I’m convinced that all these killers are trying to be heard. This is different from your typical killer who is trying to exercise authority or to get revenge. In a typical killing the killer may act in rage or may plan on getting away. In these mass killings the killer goes in with the expectation that he will not survive. It may seem senseless, but this is the act of someone who believes they are doing something of greater importance than themselves. They are using a gun, a knife, a bomb, or a car to kill but it is their way of yelling their message as loudly as they possibly can. To them, being heard is more important than life itself. </p><p>Since that’s the case, one thing we can do to prevent future killings is to do a better job at listening. But that’s not the complete solution. Some of these people are absolute nut jobs and our listening to them isn’t an option. They will confuse even a well-reasoned rebuttal of their position with ignoring them. But that might tell us something about the kind of people we should be leery of. How do they respond when people disagree with them? Do they consider the other side or do they become angry because the person won’t be swayed? </p><p>It also might tell us something about what we need to be teaching. People need to learn how to have a reasoned discussion. They also need to learn how to deal with people ignoring them. This is something that is best taught from an early age and yes, I think having a father in the home would help with this. Father’s roughhouse with their children and by doing so they teach them to fight without bringing blood. This carries over into other things. It can be how a person learns to state their case in an argument without escalating to actual harm to the other person. But it may be possible for similar things to be taught in schools. We need to bring back recess, because that’s where students learn part of these. They may also learn it if they are required to defend a point of view in class. There are some who cannot be taught and for those we may need physical prevention methods, but teaching students to deal with the insult of not being heard will only reduce the need for physical prevention measures.</p>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-2441410885412622052018-04-27T13:01:00.000-05:002018-04-27T13:01:01.449-05:00Google Censoring Religious Speech?<span class="drop-caps">I</span>t was a post shared by Mike Huckabee that caught my attention. "<a href="https://www.westernjournal.com/google-rejects-christian-publishers-ads-because-they-mention-bible-and-jesus/?utm_source=facebook&utm_medium=huckabee&utm_campaign=can&utm_content=2018-04-26" rel="nofollow" target="_blank">Google Rejects Christian Publisher's Ads Because They Mention Bible and Jesus</a>" the title read. In the current political climate it's the kind of thing that people are likely to point to as more persecution from the left or to point to as much ado about nothing from the right, depending on what their political leaning might be. So, which is it? While I respect Mike Huckabee a great deal, he isn't always so great about verifying his sources and "The Western Journal" which is were the article is located often gets things wrong. I really began to question it when I noticed that it was talking about "AdWords" and "<a href="https://support.google.com/adwordspolicy/answer/143465?hl=en" target="_blank">personalized content</a>."<br />
For those of you who don't know, "AdWords" is the term Google uses to describe advertising that targets a particular audience based on what keywords they search for. For example, if you type "coffee" into the Google search engine you are likely to start seeing ads for Starbucks, or Folgers, or coffee pots. This is because these companies are trying to target their ads at people who drink coffee. A Christian publisher like Concordia Publishing House is likely to try to target their ads at Christians, but this left me wondering why Google would tell them that they would need to remove any mention of Jesus and the Bible from their website. It didn't make sense.<br />
So, I did what anybody should do when faced with information like this. I went to the <a href="http://news.cph.org/concordia-publishing-house-responds-to-google-disabling-of-faith-based-advertising/" target="_blank">original press release.</a> While the original press release paints a similar picture and also has things are confusing about it there are things here that indicate that things are not quite what they seem. Here they refer to "remarketing ads." Remarketing ads are ads that pop up when you are trying to leave a website. Most of us find them irritating, but the basic concept is that a user visits a website and doesn't buy anything, so rather than the website getting nothing from the user the website puts an ad in front of the user so that the user will click to go to another website. Google pays a small amount for the privilege of redirecting users to another website.<br />
What many people have assumed is that Google is telling Concordia Publishing House that they can't advertise on their platform because of the content of their website, but when read the <a href="https://support.google.com/adwordspolicy/answer/143465?hl=en" target="_blank">advertising policy</a> it appears something else is going on. To paraphrase the policy, Google will not allow advertising that targets people based on a number of hot button issues. One of those is religion, but it includes other things like sexual identity, union membership, political affiliation, etc. If I'm trying to target advertising at Christians then I might want to target the keywords "Jesus" or "Bible" since those are most commonly used by Christians, but Google will reject those ads. If I were writing homosexual erotica then I might want to target "LGBT", but Google policy would reject those ads as well. Why? I suspect it is because it would be possible to use AdWords and the ads people click on for a third party to find out personal information about people. But that's still no reason for Google to suggest that Concordia Publishing House remove Jesus from their website.<br />
But let's go back to this "remarketing ads" concept. Keep in mind that Google is trying to keep third parties from finding out what the religion of the people who click on their ads is. Now, suppose that Concordia Publishing House wants to make money by allowing Google to place ads on their site. Previously, Google would've been willing, but with the concern over Cambridge Analytica they don't want the advertisers knowing that the people who clicked on their ads are coming from a religious website. So they simply say that they won't place ads on religious websites. Likewise, if they are consistent with their policy, they won't place ads on LGBT websites or on a number of other websites.<br />
Is what Google is doing a good idea? No, I don't think it is. I think there are a lot of people who are trying to advertise who won't be able to get their message to their desired audience because of this. But at the same time I'm not convinced that what they are doing with this is religious discrimination. It's more likely that this is an overreaction in an attempt to fill a huge hole in their privacy settings. As for us on the right, I think we need to be careful about jumping to conclusions.Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-54178229564139715282017-12-02T07:05:00.002-06:002017-12-02T07:05:25.481-06:00Concerning Discipleship<p><span class="drop-caps">I</span> woke up this morning with discipleship on the brain. For the past three days our church leadership has been talking discipleship and now I’m trying to figure out where that all fits. Part of my struggle is because we went through DiscipleWay training a few years ago and I can’t help but compare the two. All of the stuff we heard on night one this week seemed awfully familiar. I know we need to be making disciples who make disciples. In spite of the instructor saying that wasn’t what he was taught, I can’t say that. I grew up in a small church and for all the disadvantages of small churches, discipleship comes naturally to them. And then you have DiscipleWay, which is a very practical method of disciple making. Even if I’m not leading people through the material, I find that in teaching situations I am drawing on it to teach people the proper way to study the Bible, to pray, etc. Someone said they felt discouraged by the implication that we’ve been doing it wrong all these years. I don’t think we should be, because even if we aren’t taking people through the whole process ourselves, God can and does use multiple teachers to take people from spiritual babes to full maturity. Is there a better way? Yes. But we haven’t been wasting our time. </p><p>The most useful thing I got out of this week is a tool for assessing where people are in their spiritual development. </p><p>Things got a bit more practical on the third night, but there were some of us still asking, “But what is it that we would actually need to do?” A curriculum was mentioned and someone made the statement, “That sounds like Awana.” I don’t know what to think about that. I kind of want to fall back to DiscipleWay. That’s my comfort zone. I know how to do that. It’s very good material. I’m not so sure about something someone would describe as “Awana for adults.” But the problem with DiscipleWay is that it isn’t designed for spiritual infants. It is great for leadership development, but it isn’t something that we would plug every member and visitor of our church into. I can see it taking spiritual young adults to spiritual parenthood, but not taking spiritual infants and children to spiritual young adults. </p><p>One of the things I’ve struggled with using DiscipleWay is finding those guys to lead through the material. With the stuff we talked about this week, I don’t think we would have the same problem and actually, this new stuff could feed into DiscipleWay. I could see group leaders identifying some of their people as being ideal candidates to DiscipleWay. It was mentioned this week that Jesus had twelve disciples who went everywhere with him, but there were three that he took aside. Perhaps the three are the ones one would take through DiscipleWay, but everyone would go through some other stuff. </p><p>The big difference between what the people we talked to this week are doing and DiscipleWay is that these people are making the assumption that everyone will be in one of these groups. When they began, they literally divided their congregation up among their group leaders. They have zones in their auditorium and if someone sits in their zone the group leader in that zone asks them if they are in a group yet. In counseling situations, the pastor asks people who their group leader is and invites that leader in on the conversation. They expect that people will invite lost post to group meetings and that new membership will come through there first. </p><p>On that point, this seems to be in direct contrast with the material they taught us. There is a statement, “We can only disciple those who are…Faithful, Available, Teachable.” But if you are bringing lost people into the group and teaching spiritual infants you are including people who don’t meet that requirement. They may be available and teachable, but they aren’t faithful. If we do I job, they will be eventually, but they aren’t faithful yet.</p>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-85172258631168517972017-08-31T08:52:00.000-05:002017-08-31T08:52:07.656-05:009 Ways Not to Get Stuck Waiting for Gas<p><span class="drop-caps">G</span>asoline shortages is the word of the day. Some stations have shut off their pumps and it is expected to get worse until the refineries that were shut down by Harvey come back online. Recognizing that we are producing about twenty percent less gasoline than we normally use, we ought to drive less so that people who need gasoline the most will have it available. But let’s get real. For most of us the real concern is that we don’t want to get stuck waiting for gas at a gas station or have to go station to station until we find one that has gas. So here are nine ways to not get stuck waiting for gas.</p><br />
<h3>1. Buy Gas Early in the Morning</h3><p>The reality is that there is gas available, so if you get out before everyone else then you are more likely to find gas. During the night there are truck drivers out refilling tanks and demand for gas is low.</p><h3>2. Use the Most Fuel Efficient Vehicle</h3><p>If you have two vehicles and one uses less gas than another then you won’t have to buy as much gas. But there is a limit to that because a smaller vehicle may force you to make multiple trips.</p><h3>3. Combine Trips</h3><p>The more things you can combine into one trip the less fuel you are likely to use. For example, if you normally drive to work each weekday and do your shopping on the weekend, you can save fuel by doing your shopping on the way home from work.</p><h3>4. Use Fewer Vehicles</h3><p>Many families have a car for each person with a driver’s license. You can save fuel by family members riding together. That way, only one vehicle has to be kept filled up. You can also make use of carpooling to work. This has the added bonus that one of your co-workers ends up being the person stuck waiting for fuel rather than you.</p><h3>5. Work from Home</h3><p>If you have the option to stay home then there is no reason you have to use gasoline to get to work. </p><h3>6. Take Public Transportation</h3><p>Most people with cars tend to forget that public transportation is available. They may be slow and it may be confusing to figure out how to get to where you need to be, but they will keep you out of the line at the gas station.</p><h3>7. Walk</h3><p>This is something that almost everyone does, but they forget that it is a mode of transportation. And if you are within a mile or two of where you need to be, it may be faster to walk than it is to drive. Given that driving may also force you to wait at a gas station, walking may save you even more time.</p><h3>8. Ride a Bicycle</h3><p>For some reason this one scares people, but a bicycle can get you anywhere you want to go without gasoline. In some locations the speeds you can travel on a bicycle are higher than the average speed of automobiles on the same road, and that even before you take into account the time people spend refueling or servicing their cars.</p><h3>9. Go Electric</h3><p>Most people realize that if they had an electric car then they wouldn’t have to visit the gas station while there is a gas shortage. Not everyone has that option because they are expensive. There is, however, another way you can go electric. These days electric bicycles are becoming more popular. Maybe you aren’t physically fit enough to use a bicycle as transportation, but if you have an eBike then you can make use of an electric motor that will allow you to travel at speeds similar to those of a fit cyclist. It probably won’t save you money over driving a car, but you won’t be waiting to buy gas.</p><br />
Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0tag:blogger.com,1999:blog-8275104442398599121.post-41965968313808949532017-08-12T21:55:00.002-05:002017-08-12T21:55:29.564-05:00Addressing the Problem of Young Adults Leaving the Church<p><span class="drop-caps">W</span>hy are young adults dropping out of church? It’s a question I’ve been giving thought to lately and I write this not so much to answer the question but to put those thoughts in written form. More specifically, I’m not so interested in why young adults are dropping out as much as I’m interested in why they are missing. Of course, they would be missing if they drop out, but 30% don’t stop attending church and about 75% either don’t stop attending or they return to church. Effectively, that means there is only a 25% dropout rate, but you sure can’t tell it by looking at some churches. We often see churches where they have students and they have senior citizens, but there is a gap between the age groups. If a church is running 25 students in their children and teen ministries, they should expect to see about 35 who are between the ages of 18 and 54. A church that has fewer people between 18 and 54 than they have between 0 and 18 isn’t doing something right, but what? </p><h3>They Aren’t What We Think</h3><p>We might be tempted to look at young adults and think that they are just shallow and haven’t grown up. They just didn’t learn to be the Christians that they ought to be. And maybe there is some of that, but isn’t that what is said of every generation? 30% took a firm grasp of the faith and they are in church, even if it isn’t the church they grew up in. And then there are others who will get back into church eventually. So rather than dismiss them as being uninterested, we need to understand that a significant number of young adults want to be in church. They may not want to be in our church, but they want to be in some church. Also, they want to be in a church that teaches the truth. And they want their children involved with church programs that teach the truth. </p><h3>Preferences Are Important</h3><p>Most people don’t choose a church just because of the music, or how the auditorium looks, or how big it is. But if a person is looking at two churches that they believe both are sound in doctrine and all the other high priority things are similar, they one they choose to attend may be the one that has the music they like or the one that has more people in their age group or is the size they are looking for. The important stuff must come first, but if we have nothing for people between 18 and 55 then they are going to attend another church that puts the important stuff first and does have something for people between 18 and 55. </p><h3>Maybe We Should Question Why We Have Youth and Elderly</h3><p>Rather than trying to figure out what is causing the young and middle age adults to leave, it might be helpful to consider why we have the people that we do. Children are fairly easy to get. Offer them candy and games to play and they show up. Rent a bounce house and they show up. Teens are also pretty easy to get. Pizza works wonders and also long as they have an opportunity to spend time with their friends, they’ll be there. And when it comes to the senior citizens, you can’t bribe them with candy and pizza, but ultimately, they are also looking for an opportunity to spend time with their friends. Yes, they want to serve the Lord, but why serve at this church rather than that one over there? They will serve at the one where they have friends. They get tired of being in an empty house. A church that has activities for senior adults will have senior adults. </p><h3>The Serious Stuff Is Too Serious</h3><p>You give children candy and games. You give teens pizza and fun activities. You give senior adults an outing to hear a Southern Gospel quartet or a trip to Branson. But what do we have for young and middle age adults? “Let me tell you about this Bible study we’d like you to attend.” Or, “have you considered working in the nursery? We need some help?” It’s not that there’s anything wrong with Bible study or asking people to help in various ministries, but when you only ask people to give and they receive nothing in return they may begin to feel undervalued. Before you say, “well, it isn’t about what you get,” consider that we don’t say that of the senior adults and we don’t say that of the youth. If the people between 18 and 55 aren’t receiving some of the fun stuff that we have for the other age groups then it shouldn’t surprise us that there is a gap. Anecdotally, as a single adult I have sometimes wanted to be involved in some ministries because it would get me out of the house and around people, and yet I faced the reality that my mental wellbeing wouldn’t allow me to take on yet another serious responsibility. </p><p>One of the common problems with small groups, or Bible study, or Sunday school is that people want to sit around and talk rather than get to the lesson. Every leader has asked at some point, “How do I get people to focus on the lesson?” Maybe the problem is that people need that time to visit even more than they need yet another serious activity. </p><h3>What You Focus on Will Succeed</h3><p>As I already alluded to, we focus on children. We have special programs for children and they show up. We focus on teens. We have special programs for them and they show up. We focus on senior adults. We have people whose responsibility it is to plan special programs for them. We even have a Wednesday night service that is mostly a senior adult gathering. It is no coincidence that the one age group that doesn’t have someone assigned to it is the one that is struggling. </p><p>In church work things don’t become a priority until someone is responsible for it. Take church music, for example. I’ve seen churches where the pastor would call on someone to pick out a few songs to sing. I’ve seen visitors asked to lead the music or to sing a special. You get about what you expect from that situation and it is nothing like what you get when you have someone who knows they are responsible for the music each week. It doesn’t even have to be a paid position. </p><p>There are always competing priorities in a church. The principle of the squeaky wheel getting the grease often applies. I’m not sure that the method used by a person assigned responsibility for an age group matters as much as just having someone responsible. </p><h3>But Method Does Matter</h3><p>Let’s suppose we did have someone assigned to the 18-54 people, much like we do for other age groups. What would that look like? For one thing, I don’t think this age group is looking for additional activities. The key word here is “additional.” In this age group, they are busy with work. They are feeling guilty about not spending enough time with their children or grandchildren. The last thing we want to do is make the situation worse. </p><p>Should we assign someone to the 18-34 age and someone else to 35-54? Perhaps. But it is also possible that the overlap of the life situation between the age groups would make that counterproductive. </p><p>We can’t treat it like a senior adult ministry for younger people. If senior adults are less active then we must assume that younger adults are more active. Unfortunately, this is not always the case, but one would expect that younger adults would be more enticed by more physical activities than senior adults are. There is also work to consider. For senior adults, the best bet is to schedule an activity during daylight hours. For people who are working, you have fewer options. </p><p>But it’s not just scheduling social activities. One of the major reasons young adults drop out of church is because their work makes it impossible to attend. To be effective, the person responsible for the age group might have to become a proponent of meeting times that are more conducive for church attendance by people in that age group. </p><p>Many churches lose young adults when they move to college. If some churches lose college students then why shouldn’t some churches gain college students? The person who is assigned to reach out to young adults should be finding a way to bring some of those college students into the church. </p><h3>Summary</h3><p>It isn’t enough to ask questions about why young adults are leaving. If we want to solve the problem then we much make it a priority. That involves giving someone responsibility for solving the problem and giving them the opportunity to advocate things that will help solve the problem. Even if the person assigned to the problem doesn’t know how to solve it, having them assigned to the problem causes it to be a priority.</p>Timothy Fishhttp://www.blogger.com/profile/06554064732811895577noreply@blogger.com0